4 Replies Latest reply on Aug 22, 2017 9:39 AM by inovaovao

    Updating Last-Modified for static content served with Wildfly

    inovaovao

      I have a war with some static files (mostly images) in the webapp deployed on Wildfly. Sometimes the application needs to update some of those files, which then get replaced in the filesystem.

      However Wildfly/Undertow seem to think that nothing has changed and the Last-Modified header in the response keeps showing the time before the update.

      In fact it looks like wildfly/undertow caches the last modified time after the first time it loaded a given resource. I wonder how one can invalidade the cache for a particular path when after updating a resource.

      It's clearly a problem with the cache, since if I remove one of the files I requested before and request it again I get 500 Internal Server Error and stacktrace:

      07:25:09,823 ERROR [io.undertow.request] (default task-10) UT005023: Exception handling request to /myStore/webresources/5/header.jpg: java.lang.RuntimeException: java.nio.file.NoSuchFileException: /opt/jboss/wildfly/standalone/tmp/vfs/deployment/deployment1c84c6a78049bda8/myStore-web.war-a576c2c83124e518/webresources/5/header.jpg

              at io.undertow.server.handlers.resource.PathResource.getContentLength(PathResource.java:256)

              at org.wildfly.extension.undertow.deployment.ServletResource.getContentLength(ServletResource.java:101)

              at io.undertow.server.handlers.resource.CachedResource.getContentLength(CachedResource.java:201)

              at io.undertow.servlet.handlers.DefaultServlet.serveFileBlocking(DefaultServlet.java:293)

              at io.undertow.servlet.handlers.DefaultServlet.doGet(DefaultServlet.java:180)

              at javax.servlet.http.HttpServlet.service(HttpServlet.java:687)

              at javax.servlet.http.HttpServlet.service(HttpServlet.java:790)

              at io.undertow.servlet.handlers.ServletHandler.handleRequest(ServletHandler.java:85)

              at io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:129)

              at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:88)

              at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:76)

              at io.undertow.servlet.core.ManagedFilter.doFilter(ManagedFilter.java:61)

              at io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:131)

              at io.undertow.servlet.handlers.FilterHandler.handleRequest(FilterHandler.java:84)

              at io.undertow.servlet.handlers.security.ServletSecurityRoleHandler.handleRequest(ServletSecurityRoleHandler.java:62)

              at io.undertow.servlet.handlers.ServletDispatchingHandler.handleRequest(ServletDispatchingHandler.java:36)

              at org.wildfly.extension.undertow.security.SecurityContextAssociationHandler.handleRequest(SecurityContextAssociationHandler.java:78)

              at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)

              at io.undertow.servlet.handlers.security.SSLInformationAssociationHandler.handleRequest(SSLInformationAssociationHandler.java:131)

              at io.undertow.servlet.handlers.security.ServletAuthenticationCallHandler.handleRequest(ServletAuthenticationCallHandler.java:57)

              at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)

              at io.undertow.security.handlers.AbstractConfidentialityHandler.handleRequest(AbstractConfidentialityHandler.java:46)

              at io.undertow.servlet.handlers.security.ServletConfidentialityConstraintHandler.handleRequest(ServletConfidentialityConstraintHandler.java:64)

              at io.undertow.security.handlers.AuthenticationMechanismsHandler.handleRequest(AuthenticationMechanismsHandler.java:60)

              at io.undertow.servlet.handlers.security.CachedAuthenticatedSessionHandler.handleRequest(CachedAuthenticatedSessionHandler.java:77)

              at io.undertow.security.handlers.NotificationReceiverHandler.handleRequest(NotificationReceiverHandler.java:50)

              at io.undertow.security.handlers.AbstractSecurityContextAssociationHandler.handleRequest(AbstractSecurityContextAssociationHandler.java:43)

              at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)

              at org.wildfly.extension.undertow.security.jacc.JACCContextIdHandler.handleRequest(JACCContextIdHandler.java:61)

              at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)

              at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)

              at io.undertow.servlet.handlers.ServletInitialHandler.handleFirstRequest(ServletInitialHandler.java:292)

              at io.undertow.servlet.handlers.ServletInitialHandler.access$100(ServletInitialHandler.java:81)

              at io.undertow.servlet.handlers.ServletInitialHandler$2.call(ServletInitialHandler.java:138)

              at io.undertow.servlet.handlers.ServletInitialHandler$2.call(ServletInitialHandler.java:135)

              at io.undertow.servlet.core.ServletRequestContextThreadSetupAction$1.call(ServletRequestContextThreadSetupAction.java:48)

              at io.undertow.servlet.core.ContextClassLoaderSetupAction$1.call(ContextClassLoaderSetupAction.java:43)

              at io.undertow.servlet.api.LegacyThreadSetupActionWrapper$1.call(LegacyThreadSetupActionWrapper.java:44)

              at io.undertow.servlet.api.LegacyThreadSetupActionWrapper$1.call(LegacyThreadSetupActionWrapper.java:44)

              at io.undertow.servlet.api.LegacyThreadSetupActionWrapper$1.call(LegacyThreadSetupActionWrapper.java:44)

              at io.undertow.servlet.api.LegacyThreadSetupActionWrapper$1.call(LegacyThreadSetupActionWrapper.java:44)

              at io.undertow.servlet.api.LegacyThreadSetupActionWrapper$1.call(LegacyThreadSetupActionWrapper.java:44)

              at io.undertow.servlet.handlers.ServletInitialHandler.dispatchRequest(ServletInitialHandler.java:272)

              at io.undertow.servlet.handlers.ServletInitialHandler.access$000(ServletInitialHandler.java:81)

              at io.undertow.servlet.handlers.ServletInitialHandler$1.handleRequest(ServletInitialHandler.java:104)

              at io.undertow.server.Connectors.executeRootHandler(Connectors.java:202)

              at io.undertow.server.HttpServerExchange$1.run(HttpServerExchange.java:805)

              at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)

              at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)

              at java.lang.Thread.run(Thread.java:748)

      Caused by: java.nio.file.NoSuchFileException: /opt/jboss/wildfly/standalone/tmp/vfs/deployment/deployment1c84c6a78049bda8/myStore-web.war-a576c2c83124e518/webresources/5/header.jpg

              at sun.nio.fs.UnixException.translateToIOException(UnixException.java:86)

              at sun.nio.fs.UnixException.rethrowAsIOException(UnixException.java:102)

              at sun.nio.fs.UnixException.rethrowAsIOException(UnixException.java:107)

              at sun.nio.fs.UnixFileAttributeViews$Basic.readAttributes(UnixFileAttributeViews.java:55)

              at sun.nio.fs.UnixFileSystemProvider.readAttributes(UnixFileSystemProvider.java:144)

              at sun.nio.fs.LinuxFileSystemProvider.readAttributes(LinuxFileSystemProvider.java:99)

              at java.nio.file.Files.readAttributes(Files.java:1737)

              at java.nio.file.Files.size(Files.java:2332)

              at io.undertow.server.handlers.resource.PathResource.getContentLength(PathResource.java:254)

              ... 49 more

        • 1. Re: Updating Last-Modified for static content served with Wildfly
          ctomc

          how do you replace files?

          • 2. Re: Updating Last-Modified for static content served with Wildfly
            inovaovao

            I replace them directly on the filesystem. I find them by looking up directly the real path.

             

            The thing is that I fetch files store elsewhere and save them in the exploded war directory "/opt/jboss/wildfly/standalone/tmp/vfs/deployment/deployment1c84c6a78049bda8/myStore-web.war-a576c2c83124e518/" there they conveniently are available and can be servet as static resources. If the files are changed in the file store, they get copied again and the old one are overwritten.

            • 3. Re: Updating Last-Modified for static content served with Wildfly
              ctomc

              well that wont work, as that are internal folders & files that vfs expands there.

              server knows noting about the physical path so it doesn't know to refresh tem.

               

              for what you want to do, you should deploy your application as exploded deployment (unziped war in deployments folder)

               

              or configure undertow subsystem file handler to serve you static resources directly from some path on disk.

              • 4. Re: Updating Last-Modified for static content served with Wildfly
                inovaovao

                Ok then. But what I find strange is that if I add new files there they are found the first time. But as you say they are never refreshed. I debugged with the undertow source code and found that the CachingResourceManager that is used to get those resources is created with maxAge=-1. That means that the check for CachedResource.checkStillValid() will skip looking at the last modified date on the underlying resource and always return true.