Search code examples
tomcatcachingjbossauto-versioning

Auto-versioning of static content with JBoss


As per the Q&A here, I'd like to implement a similar auto-versioning system for a web app running in JBoss 5. Is there anything already out there to do this sort of thing, or will I need to write something myself? To be clear: I am not using PHP.

Not knowing much about PHP, I'm not sure what the Tomcat/JBoss analogs of PHP's .htaccess, etc. are. If I do have to write my own auto-versioning, where would I start? The principle is clear to me - rewriting the URL using the file's timestamp, but I don't know much about URL rewriting with JBoss/Tomcat.


Update:

Combining the approaches recommended by Pascal and novice, here's what I ended up with:

1. Custom <my:script/> and <my:style/> tags, so I wouldn't have to see <c:url/> tags everywhere.

<%@ tag body-content="empty" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ attribute name="src" required="true" rtexprvalue="true" %>
<script src="<c:url value="${src}" />"></script>

2. Following fairly closely to novice's steps, but mapping UrlRewriteFilter to /* in web.xml:

<filter-mapping>
    <filter-name>UrlRewriteFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

3. Injecting a CACHE_BUST variable to every new session (more or less...), an application deploy timestamp:

// On application deploy:
long CACHE_BUST = System.currentTimeMillis() / 1000;

// later...
session.setAttribute("cacheBust", CACHE_BUST);

4. ...so that I can use these rules in urlrewrite.xml:

<outbound-rule>
    <from>^/static/(css|js|images)/(.*)$</from>
    <to>%{context-path}/static/%{session-attribute:cacheBust}/$1/$2</to>
</outbound-rule>

<rule>
    <from>^/static/\d{10}/(css|js|images)/(.*)$</from>
    <to>/static/$1/$2</to>
</rule>

Many thanks to Pascal and novice for their help.


Solution

  • Following solution is better suited in production environment as you would be incrementing the version number for each release.

    Approach:

    • append the product release number(version number) to the js/css/images/static content urls in jsp files
    • browser would cache (js/css/static)files with the url containing the version number
    • when a new version is released, the jsp files will have the urls of js/css/static files with new version number, so the browser will make a call as it can't find the content for the new url

    Steps:

    • include urlrewritefilter.jar in the class path (get it from http://www.tuckey.org/urlrewrite/)
    • update web.xml with the url pattern, for e.g,

      <filter>
          <filter-name>urlRewriteFilter</filter-name>
          <filter-class>org.tuckey.web.filters.urlrewrite.UrlRewriteFilter</filter-class>
      </filter>
      
      <filter-mapping>
        <filter-name>urlRewriteFilter</filter-name>
        <url-pattern>/v/*</url-pattern>
      </filter-mapping>
      
    • update 'abc.js' in the jsp file, for e.g.,

      <html>
          <head>
              <script type="text/javascript" src="<c:url value="/v/js/abc.js"/>"></script>
          </head>
      </html>
      
    • write urlrewritefilter.xml, for e.g.,

      <outbound-rule>
          <from>^/v/(css|js|static)/(.*)$</from>
          <to>%{context-path}/v/updateVersionNumberHere/$1/$2</to>
      </outbound-rule>
      
      <rule>
          <from>^/v/updateVersionNumberHere/(css|js|static|images)/(.*)$</from>
          <to>/$1/$2</to>
      </rule>
      

      Explanation:

      when jsp is served to client

      • url mentioned in the jsp: /v/js/abc.js
      • after applying outbound rule: /contextPath/v/3.4.5/js/abc.js

      when browser makes a call for js/css/static files

      • incoming url: /contextPath/v/3.4.5/js/abc.js
      • after applying rule: /js/abc.js

    Points:

    • browser would catch the js files with url /contextPath/v/3.4.5/js/abc.js, next you deploy a new version of jsp files they might have the url /contextPath/v/4.5.6/js/abc.js, so the browser would make a call for js file instead of using the cached js file.
    • version updating could be automated if you use maven or similar build tool