Hello,

I've added a bug related to the use of jar entry time instead of jar file
last modified.
https://issues.apache.org/jira/browse/TAP5-1114

<https://issues.apache.org/jira/browse/TAP5-1114>Regards,
Krishna

On Fri, Apr 23, 2010 at 11:18 AM, Krishna Caldas <[email protected]>wrote:

> Hello,
>
> I have a problem with Expires and Last-Modified headers for classpath
> resources inside JBoss/Tomcat.
>
> It has seen here before:
>
> http://www.mail-archive.com/[email protected]/msg27853.html
>
> http://markmail.org/message/uwfozi756vfxd264
>
> I think its a very important issue given the performance optimization
> expected by:
>
> https://issues.apache.org/jira/browse/TAPESTRY-2159  - YSlow
> Recommendation: Version bundled javascript and use far-future expires header
>  <https://issues.apache.org/jira/browse/TAPESTRY-2159>
> I tried to write a test for this:
>
> ======================================================
> package org.apache.tapestry5.internal.util;
>
> ...
>
> public class URLChangeTrackerTest extends TapestryTestCase
> {
>     ...
>
>     @Test
>     public void lastmodified_of_jar_url_should_not_be_zero() throws
> Exception
>     {
>         URLChangeTracker t = new URLChangeTracker(converter, true);
>         URL jarFileURL = new URL("file:" +
> this.getClass().getResource("url.jar").getFile());
>         URLClassLoader classLoader = new URLClassLoader(new
> URL[]{jarFileURL});
>         URL url =
> classLoader.getResource(classLoader.getResource("url/change/tracker/Foo.txt").toString());
>         assertTrue(t.add(url) > 0);
>     }
>     ...
>
> ======================================================
>
> This tests PASSED. The error only occurs for URLs supplied by
> WebAppClassloader.
> Only inside JBoss/Tomcat.
>
> ======================================================
> package org.apache.tapestry5.ioc.internal.util;
>
> ...
>
> public final class ClasspathResource extends AbstractResource
> {
>
> ...
>
> public synchronized URL toURL()
>    {
>        if (!urlResolved)
>        {
>            *// For JBoss/Tomcat classLoader is an instance of
> org.apache.catalina.loader.WebappClassLoader*
>            url = classLoader.getResource(getPath());
>            urlResolved = true;
>        }
>
>        return url;
>    }
> ...
>
> ======================================================
>
> The proposed FIX by Geoff makes sense given that we can have distinct
> "lastmodified" dates for entries in a JAR.
> And it fixes the problem inside JBoss/Tomcat even I think they have a BUG
> because JarURLConnection should give the "lastmodified" date of the JAR.
>
> Follow some detail.
>
> Regards,
> Krishna
>
>
>
> ======================================================
>
> public class ResourceStreamerImpl implements ResourceStreamer
> {
>
> ...
>
>   public void streamResource(Resource resource) throws IOException
>    {
> ...
>
>        StreamableResource streamble =
> resourceCache.getStreamableResource(resource);
> *
>        long lastModified = streamble.getLastModified();
>
>        response.setDateHeader("Last-Modified", lastModified);
>        response.setDateHeader("Expires", lastModified +
> InternalConstants.TEN_YEARS);*
> ...
>
> ======================================================
> package org.apache.tapestry5.internal.util;
>
> ...
>
> public class URLChangeTracker
> {
>
> ...
>
>    public long add(URL url)
>    {
>        if (url == null) return 0;
>
>        URL converted = classpathURLConverter.convert(url);
>
>        if (!converted.getProtocol().equals("file")) return
> timestampForNonFileURL(converted);
> ...
>
> private long timestampForNonFileURL(URL url)
>    {
>        long timestamp;
>
>        try
>        {
>            *// Inside JBoss/Tomcat its returning 0 for JarURLConnection*
>            timestamp = url.openConnection().getLastModified();
>        }
>        catch (IOException ex)
>        {
>            throw new RuntimeException(ex);
>        }
>
>        return applyGranularity(timestamp);
>    }
>
> ...
>
> ======================================================
> package java.net;
>
> ...
>
> public abstract class URLConnection {
>
> ...
>
>    /**
>     * Returns the value of the <code>last-modified</code> header field.
>     * The result is the number of milliseconds since January 1, 1970 GMT.
>     *
>     * @return  the date the resource referenced by this
>     *          <code>URLConnection</code> was last modified, or 0 if not
> known.
>     * @see     java.net.URLConnection#getHeaderField(java.lang.String)
>     */
>    public long getLastModified() {
>    *// No header fields for JarURLConnection (extends this not overidding
> this method) inside JBoss/Tomcat.*
>    return getHeaderFieldDate("last-modified", 0);
>    }
>
> ...
>
> ======================================================
>
>

Reply via email to