ICEfaces
  1. ICEfaces
  2. ICE-8666

New resource versioning scheme for improved caching behaviour

    Details

    • Type: New Feature New Feature
    • Status: Closed
    • Priority: Major Major
    • Resolution: Fixed
    • Affects Version/s: 3.0
    • Fix Version/s: EE-3.2.0.BETA, EE-3.2.0.GA, 3.3
    • Component/s: Framework
    • Labels:
      None
    • Environment:
      ICEfaces 3.x
    • Assignee Priority:
      P1
    • Affects:
      Documentation (User Guide, Ref. Guide, etc.), Compatibility/Configuration

      Description


      JSF 2 provides a resource versioning scheme that can be used to indicate to browsers when a previously cached resource needs to be updated/reloaded.

      ICEfaces 3.0, 3.1 provide partial support for this feature, but lacks comprehensive support that would cover the ICE components, some ACE component resources, and .CSS.

      An improvement would be to provide comprehensive support for the JSF 2 resource versioning scheme for all ICEfaces resources.

        Activity

        Hide
        Ken Fyten added a comment - - edited

        Deryk:
        There is both a "library" version and "resource" version for resources. An example of using both is provided in the JSF spec and shows the final rendered resource to look like:
        basic/2_3/script.js/1_3_4.js
        Using the versions feature of JSF could help. At least with regards to resource changes between releases but I'm not sure we bundle any of our resources with a version number. For example, when I look at the ACE resources, no versioning is provided that I can see.
        The spec also states that:
        "An implementation (of a Resource Handler) may perform caching of the resource metadata to improve performance if the ProjectStage is ProjectStage.Production."
        This implies that setting ProjectStage to Development could/should prevent caching. Looking at some of our resource handling code (for example DynamicResourceDispatcher), I do see that we are setting some heading related to caching:
        externalContext.setResponseHeader("ETag", encode(resource));
        externalContext.setResponseHeader("Cache-Control", "public");
        externalContext.setResponseHeader("Content-Type", options.mimeType);
        externalContext.setResponseHeader("Last-Modified",
        Util.HTTP_DATE.format(options.lastModified));
        if (options.expiresBy != null)

        { externalContext.setResponseHeader("Expires", Util.HTTP_DATE.format(options.expiresBy)); }

        But I don't see any mechanism that might allow it to be configurable in any way or whether we honour the Development setting (at least yet, it would take me some more time to dig through it). I would have thought that if the date changed on the file then the "Last-Modified" header would have changed. Unless you go backwards with the releases - that might not trigger a reload of the cached resource if the date was actually older.

        Show
        Ken Fyten added a comment - - edited Deryk: There is both a "library" version and "resource" version for resources. An example of using both is provided in the JSF spec and shows the final rendered resource to look like: basic/2_3/script.js/1_3_4.js Using the versions feature of JSF could help. At least with regards to resource changes between releases but I'm not sure we bundle any of our resources with a version number. For example, when I look at the ACE resources, no versioning is provided that I can see. The spec also states that: "An implementation (of a Resource Handler) may perform caching of the resource metadata to improve performance if the ProjectStage is ProjectStage.Production." This implies that setting ProjectStage to Development could/should prevent caching. Looking at some of our resource handling code (for example DynamicResourceDispatcher), I do see that we are setting some heading related to caching: externalContext.setResponseHeader("ETag", encode(resource)); externalContext.setResponseHeader("Cache-Control", "public"); externalContext.setResponseHeader("Content-Type", options.mimeType); externalContext.setResponseHeader("Last-Modified", Util.HTTP_DATE.format(options.lastModified)); if (options.expiresBy != null) { externalContext.setResponseHeader("Expires", Util.HTTP_DATE.format(options.expiresBy)); } But I don't see any mechanism that might allow it to be configurable in any way or whether we honour the Development setting (at least yet, it would take me some more time to dig through it). I would have thought that if the date changed on the file then the "Last-Modified" header would have changed. Unless you go backwards with the releases - that might not trigger a reload of the cached resource if the date was actually older.
        Hide
        Deryk Sinotte added a comment - - edited

        So I logged out all the resource and library names that were triggered with:
        <icecore:config mandatoryResource="all" />
        They are printed out as [libraryName] / [resourceName] and sorted alphabetically:
        [css] / [demo_template.css]
        [css] / [override_styles.css]
        [css] / [showcase_styles.css]
        [icefaces.ace] / [autocompleteentry/autocompleteentry.js]
        [icefaces.ace] / [chart/ace-chart.js]
        [icefaces.ace] / [fileentry/fileEntry.css]
        [icefaces.ace] / [fileentry/fileEntry.js]
        [icefaces.ace] / [jquery/ui/jquery-ui.css]
        [icefaces.ace] / [richtextentry/ckeditor/ckeditor.js]
        [icefaces.ace] / [richtextentry/ckeditor/ckeditor.mapping.js]
        [icefaces.ace] / [richtextentry/richtextentry.js]
        [icefaces.ace] / [themes/sam/images/ui-bg_flat_75_ffffff_40x100.png]
        [icefaces.ace] / [themes/sam/images/ui-default.png]
        [icefaces.ace] / [themes/sam/theme.css]
        [icefaces.ace] / [util/ace-components.js]
        [icefaces.ace] / [util/ace-datatable.js]
        [icefaces.ace] / [util/ace-jquery.js]
        [icefaces.ace] / [util/ace-menu.js]
        [icefaces.ace] / [util/ace-yui.js]
        [icefaces.ace] / [util/combined.css]
        [inputrichtext] / [ckeditor_ext.js]
        [inputrichtext] / [ckeditor/ckeditor.js]
        [inputrichtext] / [ckeditor/ckeditor.mapping.js]
        [javax.faces] / [jsf.js]
        [none] / [bridge.js]
        [none] / [compat.js]
        [none] / [css/images/infoIcon.png]
        [none] / [css/images/topBannerImages/showcaseHeaderBlank.png]
        [none] / [gmap/gmap.js]
        [none] / [gmap/main.js]
        [none] / [icefaces-compat.js]
        [none] / [icefaces.ace/gmap/api.js]
        [none] / [icepush.js]
        We can likely fix most things by adding the "v=hashCode()" strategy to everything that falls under icefaces.ace library. However there are some resources that may need fixing and:
        they don't have a library (compat.js, icefaces-compat.js)
        aren't properly specifying the library ([none] / [icefaces.ace/gmap/api.js] )
        are specifying a library that's not specific enough (css, inputRichText)

        Show
        Deryk Sinotte added a comment - - edited So I logged out all the resource and library names that were triggered with: <icecore:config mandatoryResource="all" /> They are printed out as [libraryName] / [resourceName] and sorted alphabetically: [css] / [demo_template.css] [css] / [override_styles.css] [css] / [showcase_styles.css] [icefaces.ace] / [autocompleteentry/autocompleteentry.js] [icefaces.ace] / [chart/ace-chart.js] [icefaces.ace] / [fileentry/fileEntry.css] [icefaces.ace] / [fileentry/fileEntry.js] [icefaces.ace] / [jquery/ui/jquery-ui.css] [icefaces.ace] / [richtextentry/ckeditor/ckeditor.js] [icefaces.ace] / [richtextentry/ckeditor/ckeditor.mapping.js] [icefaces.ace] / [richtextentry/richtextentry.js] [icefaces.ace] / [themes/sam/images/ui-bg_flat_75_ffffff_40x100.png] [icefaces.ace] / [themes/sam/images/ui-default.png] [icefaces.ace] / [themes/sam/theme.css] [icefaces.ace] / [util/ace-components.js] [icefaces.ace] / [util/ace-datatable.js] [icefaces.ace] / [util/ace-jquery.js] [icefaces.ace] / [util/ace-menu.js] [icefaces.ace] / [util/ace-yui.js] [icefaces.ace] / [util/combined.css] [inputrichtext] / [ckeditor_ext.js] [inputrichtext] / [ckeditor/ckeditor.js] [inputrichtext] / [ckeditor/ckeditor.mapping.js] [javax.faces] / [jsf.js] [none] / [bridge.js] [none] / [compat.js] [none] / [css/images/infoIcon.png] [none] / [css/images/topBannerImages/showcaseHeaderBlank.png] [none] / [gmap/gmap.js] [none] / [gmap/main.js] [none] / [icefaces-compat.js] [none] / [icefaces.ace/gmap/api.js] [none] / [icepush.js] We can likely fix most things by adding the "v=hashCode()" strategy to everything that falls under icefaces.ace library. However there are some resources that may need fixing and: they don't have a library (compat.js, icefaces-compat.js) aren't properly specifying the library ( [none] / [icefaces.ace/gmap/api.js] ) are specifying a library that's not specific enough (css, inputRichText)
        Hide
        Deryk Sinotte added a comment -

        Resource Identification

        According to the JSF spec, a legal resource identifier consists of these parts. In effect, everything except for the resourceName is optional:

        [localePrefix/][libraryName/][libraryVersion/]resourceName[/resourceVersion]

        Ideally, our various resources would use this system so that they are not cached between updates and they could, potentially, be localized. For example, the autocomplete script file resource is currently stored as:

        META-INF/resources/icefaces.ace/autocompleteentry/autocompleteentry.js

        Assuming we release a 3.2.0 version of ICEfaces, the resource location could be changed to:

        META-INF/resources/en/icefaces.ace/3_2_0/autocompleteentry/autocompleteentry.js/1_0.js

        The spec is a bit unclear about how flat the library and resource paths have to be. It may be the case that slashes are not allowed in either one and that a library is mandatory. In other words autocompleteentry/autocompleteentry.js would be illegal and need to be switched to just autocompleteentry.js. There is some work ongoing for JSF 2.2 that is related to http://java.net/jira/browse/JAVASERVERFACES-2401.

        The rules around version formatting only provided limited flexibility on what we can put in there:

        If libraryVersion or resourceVersion are present, both must be a ’_’ separated list of integers, neither starting nor ending with ’_’

        So no using anything but numbers and underscores. We should discuss whether we think both the library versioning and the resource versioning are useful to us. The localization we could simply add as "en" for now and then if we need to different one, we already are positioned to provide it.

        Resource Caching

        The point of doing this is to allow a release of ICEfaces where our resources would be distinctly identified as to their version as well as preventing caching between our own releases. The work involved would be to:

        • change our existing directory structures to match the standard
        • automate the required processes so that the handling of the version numbers is relatively transparent during the build process

        However, doing this does not help with caching between deployments of the same release as the URL would be the same. For that, JSF provides the ProductionStage.Development setting. When that parameter is set, the JSF ResourceImpl class (at least for Mojarra) has the following logic:

            public Map<String, String> getResponseHeaders() {
        
                if (isResourceRequest()) {
                    if (responseHeaders == null)
                    responseHeaders = new HashMap<String, String>(6, 1.0f);
        
                    long expiresTime;
                    FacesContext ctx = FacesContext.getCurrentInstance();
        
                    if (ctx.isProjectStage(ProjectStage.Development)) {
                        expiresTime = new Date().getTime();
                    } else {
                        expiresTime = new Date().getTime() + maxAge;
                    }

        ...

        For Production mode, you can set the maxAge of the resources using another parameter. But in Development mode, the resources are designed to expire immediately and should therefore (in theory) be retrieved from the server every time.

        ICEfaces has a strategy where we add a request parameter, "v=hashcode()" - with the hashcode being recalculated between deployments. This doesn't quite align with what JSF is doing so we should discuss how we want that to work as well.

        Show
        Deryk Sinotte added a comment - Resource Identification According to the JSF spec, a legal resource identifier consists of these parts. In effect, everything except for the resourceName is optional: [localePrefix/][libraryName/][libraryVersion/]resourceName[/resourceVersion] Ideally, our various resources would use this system so that they are not cached between updates and they could, potentially, be localized. For example, the autocomplete script file resource is currently stored as: META-INF/resources/icefaces.ace/autocompleteentry/autocompleteentry.js Assuming we release a 3.2.0 version of ICEfaces, the resource location could be changed to: META-INF/resources/en/icefaces.ace/3_2_0/autocompleteentry/autocompleteentry.js/1_0.js The spec is a bit unclear about how flat the library and resource paths have to be. It may be the case that slashes are not allowed in either one and that a library is mandatory. In other words autocompleteentry/autocompleteentry.js would be illegal and need to be switched to just autocompleteentry.js. There is some work ongoing for JSF 2.2 that is related to http://java.net/jira/browse/JAVASERVERFACES-2401 . The rules around version formatting only provided limited flexibility on what we can put in there: If libraryVersion or resourceVersion are present, both must be a ’_’ separated list of integers, neither starting nor ending with ’_’ So no using anything but numbers and underscores. We should discuss whether we think both the library versioning and the resource versioning are useful to us. The localization we could simply add as "en" for now and then if we need to different one, we already are positioned to provide it. Resource Caching The point of doing this is to allow a release of ICEfaces where our resources would be distinctly identified as to their version as well as preventing caching between our own releases. The work involved would be to: change our existing directory structures to match the standard automate the required processes so that the handling of the version numbers is relatively transparent during the build process However, doing this does not help with caching between deployments of the same release as the URL would be the same. For that, JSF provides the ProductionStage.Development setting. When that parameter is set, the JSF ResourceImpl class (at least for Mojarra) has the following logic: public Map< String , String > getResponseHeaders() { if (isResourceRequest()) { if (responseHeaders == null ) responseHeaders = new HashMap< String , String >(6, 1.0f); long expiresTime; FacesContext ctx = FacesContext.getCurrentInstance(); if (ctx.isProjectStage(ProjectStage.Development)) { expiresTime = new Date().getTime(); } else { expiresTime = new Date().getTime() + maxAge; } ... For Production mode, you can set the maxAge of the resources using another parameter. But in Development mode, the resources are designed to expire immediately and should therefore (in theory) be retrieved from the server every time. ICEfaces has a strategy where we add a request parameter, "v=hashcode()" - with the hashcode being recalculated between deployments. This doesn't quite align with what JSF is doing so we should discuss how we want that to work as well.
        Hide
        Deryk Sinotte added a comment -

        As per the discussion in our last status meeting:

        • We need to prototype the JSF versioning scheme with some of our core resource files and then promote the solution to the rest of the product.
        • Since Mojarra already has the potential capability to adjust caching by setting the ProductStage to Development, we should respect this setting as well. We'll need to check if this works with relatively modern versions of IE to ensure it will work for our customers.
        • Assuming all the above works, we'll probably want to remove our own v=hashcode() parameter technique.
        Show
        Deryk Sinotte added a comment - As per the discussion in our last status meeting: We need to prototype the JSF versioning scheme with some of our core resource files and then promote the solution to the rest of the product. Since Mojarra already has the potential capability to adjust caching by setting the ProductStage to Development, we should respect this setting as well. We'll need to check if this works with relatively modern versions of IE to ensure it will work for our customers. Assuming all the above works, we'll probably want to remove our own v=hashcode() parameter technique.
        Hide
        Deryk Sinotte added a comment -

        So I attempted to prototype the changes required for converting our "bridge.js" file to use the JSF versioning system. The first step was easy enough, changing our Ant builds so that instead of:

        • icefaces/core/build/javascript/resources/bridge.js
        • icefaces/core/build/javascript/resources/bridge.ucompressed.js

        the resulting files are built out into:

        • icefaces/core/build/javascript/resources/en/ice.core/3_3_0/bridge.js
        • icefaces/core/build/javascript/resources/en/ice.core/3_3_0/bridge.ucompressed.js

        This adds the localization and library version to each file and can be controlled using properties in the build files themselves.

        According to the spec, the encoding and versioning is transparent from the API perspective. This means that when you request a resource, you only resource name and (optionally) the library name to get the resource. The correct encoding and version is chosen automatically.

        The benefits are that you can potentially upgrade the library version of a set of resources (e.g. with a patch) and have those resources served automatically. This benefit is described in one of the early, seminal blogs on the matter:

        https://blogs.oracle.com/rlubke/entry/jsf_2_0_new_feature5

        There's a good summary in that blog of the 2 default locations where resources are looked for in order:

        1. /resources this location represents resources in the webapp itself and, if present, must be in the root of the web application
        2. /META-INF/resources this location represents resources on the classpath

        All good up to this point. However, in reality, the "versioning" of resources doesn't work if the resources are located on the classpath (/META-INF/resources inside a jar file). Information on why this is and how the spec is changing are rather sketchy. I eventually tracked some JIRAs down:

        http://java.net/jira/browse/JAVASERVERFACES-1423
        http://java.net/jira/browse/JAVASERVERFACES-2100
        http://java.net/jira/browse/JAVASERVERFACES_SPEC_PUBLIC-630

        Apparently the feature couldn't be implemented in a portable fashion so it just wasn't done. Not sure what this says for the future of the versioning feature.

        In any event, we've decided to take a slightly different tack. We can still adjust the builds to add the encoding, library names, etc into our resources. But instead of adding the versioning as part of the path, we'll adjust some of resource handling code so that all of our resources provide something similar to the v=hashcode() parameter that we already implement in certain situations. However, instead of a hashcode(), we'll append the version that matches the current release, somewhat simulating what JSF would do if there was a version (e.g. ...&v=3_2_0). The plan is to also add a timestamp to help differentiate releases that have the same version (OS vs EE) but were released at different times. We will also likely use it as a mechanism for differentiating patches.

        Show
        Deryk Sinotte added a comment - So I attempted to prototype the changes required for converting our "bridge.js" file to use the JSF versioning system. The first step was easy enough, changing our Ant builds so that instead of: icefaces/core/build/javascript/resources/bridge.js icefaces/core/build/javascript/resources/bridge.ucompressed.js the resulting files are built out into: icefaces/core/build/javascript/resources/en/ice.core/3_3_0/bridge.js icefaces/core/build/javascript/resources/en/ice.core/3_3_0/bridge.ucompressed.js This adds the localization and library version to each file and can be controlled using properties in the build files themselves. According to the spec, the encoding and versioning is transparent from the API perspective. This means that when you request a resource, you only resource name and (optionally) the library name to get the resource. The correct encoding and version is chosen automatically. The benefits are that you can potentially upgrade the library version of a set of resources (e.g. with a patch) and have those resources served automatically. This benefit is described in one of the early, seminal blogs on the matter: https://blogs.oracle.com/rlubke/entry/jsf_2_0_new_feature5 There's a good summary in that blog of the 2 default locations where resources are looked for in order: /resources this location represents resources in the webapp itself and, if present, must be in the root of the web application /META-INF/resources this location represents resources on the classpath All good up to this point. However, in reality, the "versioning" of resources doesn't work if the resources are located on the classpath (/META-INF/resources inside a jar file). Information on why this is and how the spec is changing are rather sketchy. I eventually tracked some JIRAs down: http://java.net/jira/browse/JAVASERVERFACES-1423 http://java.net/jira/browse/JAVASERVERFACES-2100 http://java.net/jira/browse/JAVASERVERFACES_SPEC_PUBLIC-630 Apparently the feature couldn't be implemented in a portable fashion so it just wasn't done. Not sure what this says for the future of the versioning feature. In any event, we've decided to take a slightly different tack. We can still adjust the builds to add the encoding, library names, etc into our resources. But instead of adding the versioning as part of the path, we'll adjust some of resource handling code so that all of our resources provide something similar to the v=hashcode() parameter that we already implement in certain situations. However, instead of a hashcode(), we'll append the version that matches the current release, somewhat simulating what JSF would do if there was a version (e.g. ...&v=3_2_0). The plan is to also add a timestamp to help differentiate releases that have the same version (OS vs EE) but were released at different times. We will also likely use it as a mechanism for differentiating patches.
        Hide
        Deryk Sinotte added a comment -

        I've had some success adding libraries and versioning to the core-based resources (bridge.js, icepush.js, compat*, etc). The feature currently tacks on "v=3_3_0_121412" to the URL of those resources by default. The version is based on the current version in the properties files and the date is the build date and is updated with each build. The feature can be turned off using the existing org.icefaces.uniqueResourceURL=false context parameter. It can also be overridden by specifying org.icefaces.resourceVersion=1_2_3_4_5555 if desired. I tested with both the compressed and uncompressed versions by changing the ProductionStage setting.

        Most of the other component based resources are a bit more difficult as they are mostly added in using the ResourceDependency annotation. I'm currently trying some ways in the ResourceOrdering class to rewrap the default UIOutput components with something that will include the versioning scheme.

        Show
        Deryk Sinotte added a comment - I've had some success adding libraries and versioning to the core-based resources (bridge.js, icepush.js, compat*, etc). The feature currently tacks on "v=3_3_0_121412" to the URL of those resources by default. The version is based on the current version in the properties files and the date is the build date and is updated with each build. The feature can be turned off using the existing org.icefaces.uniqueResourceURL=false context parameter. It can also be overridden by specifying org.icefaces.resourceVersion=1_2_3_4_5555 if desired. I tested with both the compressed and uncompressed versions by changing the ProductionStage setting. Most of the other component based resources are a bit more difficult as they are mostly added in using the ResourceDependency annotation. I'm currently trying some ways in the ResourceOrdering class to rewrap the default UIOutput components with something that will include the versioning scheme.
        Hide
        Deryk Sinotte added a comment -

        So the work to add resource versioning capabilities took a different tack from the last comment. Rather than simply add a version attribute to the components in the ResourceOrdering (which didn't appear to be processed and rendered internally by Mojarra), we attacked the problem with a ResourceHandler:

        • Added a new VersioningResourceHandler in our core library. The purpose of this ResourceHandler is to override the createResource() method and wrap any resources that pass through with VersionedResource wrapper. The wrapped overrides the getRequestPath() method of the resource, modifying the current request path of the resource by adding a "v=" parameter.
        • The versioning logic is only applied if the following context parameter is true (which is the current default). Setting it to false will turn off the versioning. This is the same behaviour we had before with the previous versioning:
        <context-param>
            <param-name>org.icefaces.uniqueResourceURLs</param-name>
            <param-value>false</param-value>
        </context-param>
        
        • Adjusted the core, compat, and icepush build files so that our main libraries (e.g bridge.js, *compat.js, icepush.js) are now built and served out of library directories (ice.core, ice.compat, ice.push). While not strictly necessary, I believe it's a best practice. And should we need to in the future, we could better control versioning based on our library names. Right now there are still some component and example resource that don't have libraries.
        • Removed all the old versioning logic that I could find (BridgeSetup, ExtrasSetup, MandatoryResource, etc). The VersionResourceHandler centralizes the feature and should make it easier to find and modify going forward. I also removed a number of other Resource style classes we were using and put all the logic into a single, simpler class called ResourceOutputUtil.
        • The actual value of the version parameter is controlled in the build properties and filtered into the ProductInfo class. The current version properties are used as well as a couple of new properties. The version is calculated by taking the current version number and appending the build date (yymmdd). By default, it looks like:
          • v=3_3_0_121218
        • There is another optional value that can be specified. By default, there is no version.patch property specified in top build.properties file. Provided a value for this property and then rebuilding will update the version value to include a patch number:
          • version.patch=0001
          • v=3_3_0_121218_0001
        • I also included a new context parameter called org.icefaces.resourceVersion. If not set, it simply defaults to what was calculated in the ProductInfo class. If set, it will override any version that was calculated from the ProductInfo class. I don't imagine documenting or using this but I added it so that it would print out in the list of context parameters for debugging purposes as well as being easily accessible from EnvUtils.getResourceVersion().
        <context-param>
            <param-name>org.icefaces.resourceVersion</param-name>
            <param-value>1_2_3_4_55555</param-value>
        </context-param>
        
        Show
        Deryk Sinotte added a comment - So the work to add resource versioning capabilities took a different tack from the last comment. Rather than simply add a version attribute to the components in the ResourceOrdering (which didn't appear to be processed and rendered internally by Mojarra), we attacked the problem with a ResourceHandler: Added a new VersioningResourceHandler in our core library. The purpose of this ResourceHandler is to override the createResource() method and wrap any resources that pass through with VersionedResource wrapper. The wrapped overrides the getRequestPath() method of the resource, modifying the current request path of the resource by adding a "v=" parameter. The versioning logic is only applied if the following context parameter is true (which is the current default). Setting it to false will turn off the versioning. This is the same behaviour we had before with the previous versioning: <context-param> <param-name>org.icefaces.uniqueResourceURLs</param-name> <param-value> false </param-value> </context-param> Adjusted the core, compat, and icepush build files so that our main libraries (e.g bridge.js, *compat.js, icepush.js) are now built and served out of library directories (ice.core, ice.compat, ice.push). While not strictly necessary, I believe it's a best practice. And should we need to in the future, we could better control versioning based on our library names. Right now there are still some component and example resource that don't have libraries. Removed all the old versioning logic that I could find (BridgeSetup, ExtrasSetup, MandatoryResource, etc). The VersionResourceHandler centralizes the feature and should make it easier to find and modify going forward. I also removed a number of other Resource style classes we were using and put all the logic into a single, simpler class called ResourceOutputUtil. The actual value of the version parameter is controlled in the build properties and filtered into the ProductInfo class. The current version properties are used as well as a couple of new properties. The version is calculated by taking the current version number and appending the build date (yymmdd). By default, it looks like: v=3_3_0_121218 There is another optional value that can be specified. By default, there is no version.patch property specified in top build.properties file. Provided a value for this property and then rebuilding will update the version value to include a patch number: version.patch=0001 v=3_3_0_121218_0001 I also included a new context parameter called org.icefaces.resourceVersion. If not set, it simply defaults to what was calculated in the ProductInfo class. If set, it will override any version that was calculated from the ProductInfo class. I don't imagine documenting or using this but I added it so that it would print out in the list of context parameters for debugging purposes as well as being easily accessible from EnvUtils.getResourceVersion(). <context-param> <param-name>org.icefaces.resourceVersion</param-name> <param-value>1_2_3_4_55555</param-value> </context-param>
        Hide
        Deryk Sinotte added a comment -

        Ken tested it and gave it a thumbs up.

        Show
        Deryk Sinotte added a comment - Ken tested it and gave it a thumbs up.

          People

          • Assignee:
            Deryk Sinotte
            Reporter:
            Ken Fyten
          • Votes:
            0 Vote for this issue
            Watchers:
            3 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved: