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