You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@struts.apache.org by lu...@apache.org on 2021/01/02 16:52:45 UTC

[struts] 01/01: WW-5021 Introduces a new constant to allow define a path to static content

This is an automated email from the ASF dual-hosted git repository.

lukaszlenart pushed a commit to branch WW-5021-static-content-path
in repository https://gitbox.apache.org/repos/asf/struts.git

commit ef72783f502e5773ab630d1f4238efc27b6c554f
Author: Lukasz Lenart <lu...@apache.org>
AuthorDate: Sat Jan 2 17:52:29 2021 +0100

    WW-5021 Introduces a new constant to allow define a path to static content
---
 .../apache/struts2/showcase/StaticContentTest.java |  4 +-
 .../admin/src/main/resources/osgi/admin/shell.ftl  | 12 ++---
 .../src/main/resources/osgi/admin/viewBundle.ftl   |  8 +--
 .../src/main/resources/osgi/admin/viewBundles.ftl  |  8 +--
 .../java/org/apache/struts2/StrutsConstants.java   |  3 ++
 .../java/org/apache/struts2/components/UIBean.java | 11 +++-
 .../struts2/config/entities/ConstantConfig.java    | 10 ++++
 .../dispatcher/DefaultStaticContentLoader.java     | 60 +++++++++++++---------
 .../struts2/dispatcher/StaticContentLoader.java    |  7 ++-
 .../org/apache/struts2/default.properties          |  3 ++
 .../resources/template/css_xhtml/form-validate.ftl |  2 +-
 .../src/main/resources/template/css_xhtml/head.ftl |  2 +-
 .../template/simple/form-close-tooltips.ftl        |  4 +-
 core/src/main/resources/template/simple/head.ftl   |  2 +-
 .../template/simple/inputtransferselect.ftl        |  2 +-
 .../template/simple/optiontransferselect.ftl       |  2 +-
 .../resources/template/simple/updownselect.ftl     |  2 +-
 .../resources/template/xhtml/form-validate.ftl     |  2 +-
 core/src/main/resources/template/xhtml/head.ftl    |  2 +-
 core/src/main/resources/template/xhtml/tooltip.ftl |  2 +-
 .../dispatcher/DefaultStaticContentLoaderTest.java |  7 +--
 .../dispatcher/StaticContentLoaderTest.java        | 18 ++++---
 ...rutsPrepareAndExecuteFilterIntegrationTest.java |  2 +-
 .../dispatcher/TwoFilterIntegrationTest.java       |  2 +-
 .../apache/struts2/views/jsp/ui/TooltipTest.java   | 26 +++++-----
 .../org/apache/struts2/views/jsp/ui/Formtag-11.txt |  4 +-
 .../org/apache/struts2/views/jsp/ui/Formtag-2.txt  |  4 +-
 .../org/apache/struts2/views/jsp/ui/Formtag-22.txt |  4 +-
 .../org/apache/struts2/views/jsp/ui/Formtag-24.txt |  4 +-
 .../org/apache/struts2/views/jsp/ui/Formtag-6.txt  |  2 +-
 .../apache/struts2/views/jsp/ui/HeadTagTest-1.txt  |  4 +-
 .../struts2/views/jsp/ui/inputtransferselect-1.txt |  2 +-
 .../views/jsp/ui/optiontransferselect-1.txt        |  2 +-
 .../views/jsp/ui/optiontransferselect-2.txt        |  2 +-
 .../views/jsp/ui/optiontransferselect-3.txt        |  2 +-
 .../views/jsp/ui/optiontransferselect-4.txt        |  2 +-
 .../views/jsp/ui/optiontransferselect-5.txt        |  2 +-
 .../views/jsp/ui/optiontransferselect-6.txt        |  2 +-
 .../views/jsp/ui/optiontransferselect-7.txt        |  2 +-
 .../org/apache/struts2/views/jsp/ui/tooltip-1.txt  |  6 +--
 .../org/apache/struts2/views/jsp/ui/tooltip-2.txt  |  6 +--
 .../org/apache/struts2/views/jsp/ui/tooltip-3.txt  |  6 +--
 .../org/apache/struts2/views/jsp/ui/tooltip-4.txt  |  2 +-
 .../struts2/views/jsp/ui/updownselecttag-1.txt     |  2 +-
 .../struts2/views/jsp/ui/updownselecttag-10.txt    |  2 +-
 .../struts2/views/jsp/ui/updownselecttag-11.txt    |  2 +-
 .../struts2/views/jsp/ui/updownselecttag-2.txt     |  2 +-
 .../struts2/views/jsp/ui/updownselecttag-3.txt     |  2 +-
 .../struts2/views/jsp/ui/updownselecttag-4.txt     |  2 +-
 .../struts2/views/jsp/ui/updownselecttag-5.txt     |  2 +-
 .../struts2/views/jsp/ui/updownselecttag-6.txt     |  2 +-
 .../struts2/views/jsp/ui/updownselecttag-7.txt     |  2 +-
 .../struts2/views/jsp/ui/updownselecttag-8.txt     |  2 +-
 .../struts2/views/jsp/ui/updownselecttag-9.txt     |  2 +-
 .../struts2/views/java/simple/HeadHandler.java     |  2 +-
 .../apache/struts2/views/java/simple/HeadTest.java |  2 +-
 56 files changed, 163 insertions(+), 124 deletions(-)

diff --git a/apps/showcase/src/test/java/it/org/apache/struts2/showcase/StaticContentTest.java b/apps/showcase/src/test/java/it/org/apache/struts2/showcase/StaticContentTest.java
index 8e274dd..06057f9 100644
--- a/apps/showcase/src/test/java/it/org/apache/struts2/showcase/StaticContentTest.java
+++ b/apps/showcase/src/test/java/it/org/apache/struts2/showcase/StaticContentTest.java
@@ -40,7 +40,7 @@ public class StaticContentTest {
     public void testInvalidRersources2() throws Exception {
         try (final WebClient webClient = new WebClient()) {
             try {
-                webClient.getPage(ParameterUtils.getBaseUrl() + "/struts/..%252f");
+                webClient.getPage(ParameterUtils.getBaseUrl() + "/static/..%252f");
                 Assert.fail("Previous request should have failed");
             } catch (FailingHttpStatusCodeException e) {
             }
@@ -49,7 +49,7 @@ public class StaticContentTest {
 
     /*public void testInvalidRersources3() throws IOException {
         try {
-            beginAt("/struts/..%252f..%252f..%252fWEB-INF/classes/org/apache/struts2/showcase/action/EmployeeAction.class/");
+            beginAt("/static/..%252f..%252f..%252fWEB-INF/classes/org/apache/struts2/showcase/action/EmployeeAction.class/");
             fail("Previous request should have failed");
         } catch (TestingEngineResponseException ex) {
             // ok
diff --git a/bundles/admin/src/main/resources/osgi/admin/shell.ftl b/bundles/admin/src/main/resources/osgi/admin/shell.ftl
index aa7d8a9..62d0cce 100644
--- a/bundles/admin/src/main/resources/osgi/admin/shell.ftl
+++ b/bundles/admin/src/main/resources/osgi/admin/shell.ftl
@@ -22,13 +22,13 @@
     <head>
         <title>OSGi Console</title>
 
-        <link rel="stylesheet" type="text/css" href="<@s.url value="/static/css/shell.css" />" />
-        <link rel="stylesheet" type="text/css" href="<@s.url value="/static/css/main.css" />" />
-        <link rel="stylesheet" type="text/css" href="<@s.url value="/static/css/redmond/jquery-ui-1.12.1.redmond.css" />" />
+        <link rel="stylesheet" type="text/css" href="<@s.url value="${parameters.staticContentPath}/css/shell.css" />" />
+        <link rel="stylesheet" type="text/css" href="<@s.url value="${parameters.staticContentPath}/css/main.css" />" />
+        <link rel="stylesheet" type="text/css" href="<@s.url value="${parameters.staticContentPath}/css/redmond/jquery-ui-1.12.1.redmond.css" />" />
 
-        <script src="<@s.url value="/static/js/shell.js" />"></script>
-        <script src="<@s.url value="/static/js/jquery-1.12.4.min.js" />"></script>
-        <script src="<@s.url value="/static/js/jquery-ui-1.12.1.min.js" />"></script>
+        <script src="<@s.url value="${parameters.staticContentPath}/js/shell.js" />"></script>
+        <script src="<@s.url value="${parameters.staticContentPath}/js/jquery-1.12.4.min.js" />"></script>
+        <script src="<@s.url value="${parameters.staticContentPath}/js/jquery-ui-1.12.1.min.js" />"></script>
     </head>
 <body>
 <div class="menu">
diff --git a/bundles/admin/src/main/resources/osgi/admin/viewBundle.ftl b/bundles/admin/src/main/resources/osgi/admin/viewBundle.ftl
index 64ebbb9..97f22a3 100644
--- a/bundles/admin/src/main/resources/osgi/admin/viewBundle.ftl
+++ b/bundles/admin/src/main/resources/osgi/admin/viewBundle.ftl
@@ -22,11 +22,11 @@
     <head>
         <title>${bundle.symbolicName!}</title>
 
-        <link rel="stylesheet" type="text/css" href="<@s.url value="/static/css/main.css" />" />
-        <link rel="stylesheet" type="text/css" href="<@s.url value="/static/css/redmond/jquery-ui-1.12.1.redmond.css" />" />
+        <link rel="stylesheet" type="text/css" href="<@s.url value="${parameters.staticContentPath}/css/main.css" />" />
+        <link rel="stylesheet" type="text/css" href="<@s.url value="${parameters.staticContentPath}/css/redmond/jquery-ui-1.12.1.redmond.css" />" />
 
-        <script src="<@s.url value="/static/js/jquery-1.12.4.min.js" />"></script>
-        <script src="<@s.url value="/static/js/jquery-ui-1.12.1.min.js" />"></script>
+        <script src="<@s.url value="${parameters.staticContentPath}/js/jquery-1.12.4.min.js" />"></script>
+        <script src="<@s.url value="${parameters.staticContentPath}/js/jquery-ui-1.12.1.min.js" />"></script>
 
         <script type="text/javascript">
             $(function() {
diff --git a/bundles/admin/src/main/resources/osgi/admin/viewBundles.ftl b/bundles/admin/src/main/resources/osgi/admin/viewBundles.ftl
index 63f7235..f20fed8 100644
--- a/bundles/admin/src/main/resources/osgi/admin/viewBundles.ftl
+++ b/bundles/admin/src/main/resources/osgi/admin/viewBundles.ftl
@@ -22,11 +22,11 @@
     <head>
         <title>OSGi Bundles</title>
 
-        <link rel="stylesheet" type="text/css" href="<@s.url value="/static/css/main.css" />" />
-        <link rel="stylesheet" type="text/css" href="<@s.url value="/static/css/redmond/jquery-ui-1.12.1.redmond.css" />" />
+        <link rel="stylesheet" type="text/css" href="<@s.url value="${parameters.staticContentPath}/css/main.css" />" />
+        <link rel="stylesheet" type="text/css" href="<@s.url value="${parameters.staticContentPath}/css/redmond/jquery-ui-1.12.1.redmond.css" />" />
 
-        <script src="<@s.url value="/static/js/jquery-1.12.4.min.js" />"></script>
-        <script src="<@s.url value="/static/js/jquery-ui-1.12.1.min.js" />"></script>
+        <script src="<@s.url value="${parameters.staticContentPath}/js/jquery-1.12.4.min.js" />"></script>
+        <script src="<@s.url value="${parameters.staticContentPath}/js/jquery-ui-1.12.1.min.js" />"></script>
     </head>
 <body>
 
diff --git a/core/src/main/java/org/apache/struts2/StrutsConstants.java b/core/src/main/java/org/apache/struts2/StrutsConstants.java
index 45b44a6..2d22c34 100644
--- a/core/src/main/java/org/apache/struts2/StrutsConstants.java
+++ b/core/src/main/java/org/apache/struts2/StrutsConstants.java
@@ -118,6 +118,9 @@ public final class StrutsConstants {
     /** Token to use to indicate start of theme to be expanded. */
     public static final String STRUTS_UI_THEME_EXPANSION_TOKEN = "struts.ui.theme.expansion.token";
 
+    /** A path to static content, by default and from historical point of view it's /static. */
+    public static final String STRUTS_UI_STATIC_CONTENT_PATH = "struts.ui.staticContentPath";
+
     /** The maximize size of a multipart request (file upload) */
     public static final String STRUTS_MULTIPART_MAXSIZE = "struts.multipart.maxSize";
 
diff --git a/core/src/main/java/org/apache/struts2/components/UIBean.java b/core/src/main/java/org/apache/struts2/components/UIBean.java
index 68fff20..1586a55 100644
--- a/core/src/main/java/org/apache/struts2/components/UIBean.java
+++ b/core/src/main/java/org/apache/struts2/components/UIBean.java
@@ -317,7 +317,7 @@ import java.util.Map;
  *    <tr>
  *      <td>tooltipIcon</td>
  *      <td>String</td>
- *      <td>/struts/static/tooltip/tooltip.gif</td>
+ *      <td>/static/tooltip/tooltip.gif</td>
  *      <td>The url to the tooltip icon</td>
  *   <tr>
  *      <td>tooltipDelay</td>
@@ -506,6 +506,8 @@ public abstract class UIBean extends Component {
     protected String defaultTemplateDir;
     protected String defaultUITheme;
     protected String uiThemeExpansionToken;
+    protected String uiStaticContentPath;
+
     protected TemplateEngineManager templateEngineManager;
 
     @Inject(StrutsConstants.STRUTS_UI_TEMPLATEDIR)
@@ -523,6 +525,11 @@ public abstract class UIBean extends Component {
         this.uiThemeExpansionToken = uiThemeExpansionToken;
     }
 
+    @Inject(StrutsConstants.STRUTS_UI_STATIC_CONTENT_PATH)
+    public void setUiStaticContentPath(String uiStaticContentPath) {
+        this.uiStaticContentPath = uiStaticContentPath;
+    }
+
     @Inject
     public void setTemplateEngineManager(TemplateEngineManager mgr) {
         this.templateEngineManager = mgr;
@@ -645,6 +652,8 @@ public abstract class UIBean extends Component {
         addParameter("themeExpansionToken", uiThemeExpansionToken);
         addParameter("expandTheme", uiThemeExpansionToken + theme);
 
+        addParameter("staticContentPath", findString(uiStaticContentPath));
+
         String name = null;
         String providedLabel = null;
 
diff --git a/core/src/main/java/org/apache/struts2/config/entities/ConstantConfig.java b/core/src/main/java/org/apache/struts2/config/entities/ConstantConfig.java
index 6d9be83..2ea04fd 100644
--- a/core/src/main/java/org/apache/struts2/config/entities/ConstantConfig.java
+++ b/core/src/main/java/org/apache/struts2/config/entities/ConstantConfig.java
@@ -143,6 +143,7 @@ public class ConstantConfig {
     private BeanConfig localizedTextProvider;
     private Boolean disallowProxyMemberAccess;
     private Integer ognlAutoGrowthCollectionLimit;
+    private String staticContentPath;
 
     protected String beanConfToString(BeanConfig beanConf) {
         return beanConf == null ? null : beanConf.getName();
@@ -273,6 +274,7 @@ public class ConstantConfig {
         map.put(StrutsConstants.STRUTS_LOCALIZED_TEXT_PROVIDER, beanConfToString(localizedTextProvider));
         map.put(StrutsConstants.STRUTS_DISALLOW_PROXY_MEMBER_ACCESS, Objects.toString(disallowProxyMemberAccess, null));
         map.put(StrutsConstants.STRUTS_OGNL_AUTO_GROWTH_COLLECTION_LIMIT, Objects.toString(ognlAutoGrowthCollectionLimit, null));
+        map.put(StrutsConstants.STRUTS_UI_STATIC_CONTENT_PATH, Objects.toString(staticContentPath, null));
 
         return map;
     }
@@ -1344,4 +1346,12 @@ public class ConstantConfig {
     public void setOgnlAutoGrowthCollectionLimit(Integer ognlAutoGrowthCollectionLimit) {
         this.ognlAutoGrowthCollectionLimit = ognlAutoGrowthCollectionLimit;
     }
+
+    public String getStaticContentPath() {
+        return staticContentPath;
+    }
+
+    public void setStaticContentPath(String staticContentPath) {
+        this.staticContentPath = staticContentPath;
+    }
 }
diff --git a/core/src/main/java/org/apache/struts2/dispatcher/DefaultStaticContentLoader.java b/core/src/main/java/org/apache/struts2/dispatcher/DefaultStaticContentLoader.java
index 42f1716..c633c1d 100644
--- a/core/src/main/java/org/apache/struts2/dispatcher/DefaultStaticContentLoader.java
+++ b/core/src/main/java/org/apache/struts2/dispatcher/DefaultStaticContentLoader.java
@@ -34,7 +34,12 @@ import java.io.OutputStream;
 import java.io.UnsupportedEncodingException;
 import java.net.URL;
 import java.net.URLDecoder;
-import java.util.*;
+import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.Collections;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.StringTokenizer;
 
 /**
  * <p>
@@ -43,8 +48,8 @@ import java.util.*;
  *
  * <p>
  * This class is used to serve common static content needed when using various parts of Struts, such as JavaScript
- * files, CSS files, etc. It works by looking for requests to /struts/* (or /static/*), and then mapping the value after "/struts/"
- * to common packages in Struts and, optionally, in your class path. By default, the following packages are
+ * files, CSS files, etc. It works by looking for requests to {@link #staticContentPath}/*  and then mapping the value
+ * after to common packages in Struts and, optionally, in your class path. By default, the following packages are
  * automatically searched:
  * </p>
  *
@@ -55,7 +60,7 @@ import java.util.*;
  * </ul>
  *
  * <p>
- * This means that you can simply request /struts/xhtml/styles.css and the XHTML UI theme's default stylesheet
+ * This means that you can simply request {@link #staticContentPath}/xhtml/styles.css and the XHTML UI theme's default stylesheet
  * will be returned. Likewise, many of the AJAX UI components require various JavaScript files, which are found in the
  * org.apache.struts2.static package. If you wish to add additional packages to be searched, you can add a comma
  * separated (space, tab and new line will do as well) list in the filter init parameter named "packages". <b>Be
@@ -68,7 +73,7 @@ public class DefaultStaticContentLoader implements StaticContentLoader {
     /**
      * Provide a logging instance.
      */
-    private Logger LOG = LogManager.getLogger(DefaultStaticContentLoader.class);
+    private final Logger LOG = LogManager.getLogger(DefaultStaticContentLoader.class);
 
     /**
      * Store set of path prefixes to use with static resources.
@@ -81,6 +86,11 @@ public class DefaultStaticContentLoader implements StaticContentLoader {
     protected boolean serveStatic;
 
     /**
+     * Store state of StrutsConstants.STRUTS_STATIC_CONTENT_PATH setting.
+     */
+    protected String staticContentPath;
+
+    /**
      * Store state of StrutsConstants.STRUTS_SERVE_STATIC_BROWSER_CACHE setting.
      */
     protected boolean serveStaticBrowserCache;
@@ -100,20 +110,23 @@ public class DefaultStaticContentLoader implements StaticContentLoader {
     /**
      * Modify state of StrutsConstants.STRUTS_SERVE_STATIC_CONTENT setting.
      *
-     * @param serveStaticContent
-     *            New setting
+     * @param serveStaticContent New setting
      */
     @Inject(StrutsConstants.STRUTS_SERVE_STATIC_CONTENT)
     public void setServeStaticContent(String serveStaticContent) {
         this.serveStatic = BooleanUtils.toBoolean(serveStaticContent);
     }
 
+    @Inject(StrutsConstants.STRUTS_UI_STATIC_CONTENT_PATH)
+    public void setStaticContentPath(String staticContentPath) {
+        this.staticContentPath = staticContentPath;
+    }
+
     /**
      * Modify state of StrutsConstants.STRUTS_SERVE_STATIC_BROWSER_CACHE
      * setting.
      *
-     * @param serveStaticBrowserCache
-     *            New setting
+     * @param serveStaticBrowserCache New setting
      */
     @Inject(StrutsConstants.STRUTS_SERVE_STATIC_BROWSER_CACHE)
     public void setServeStaticBrowserCache(String serveStaticBrowserCache) {
@@ -122,6 +135,7 @@ public class DefaultStaticContentLoader implements StaticContentLoader {
 
     /**
      * Modify state of StrutsConstants.STRUTS_I18N_ENCODING setting.
+     *
      * @param encoding New setting
      */
     @Inject(StrutsConstants.STRUTS_I18N_ENCODING)
@@ -164,8 +178,7 @@ public class DefaultStaticContentLoader implements StaticContentLoader {
     /**
      * Create a string array from a comma-delimited list of packages.
      *
-     * @param packages
-     *            A comma-delimited String listing packages
+     * @param packages A comma-delimited String listing packages
      * @return A string array of packages
      */
     protected List<String> parse(String packages) {
@@ -194,7 +207,7 @@ public class DefaultStaticContentLoader implements StaticContentLoader {
      *      javax.servlet.http.HttpServletResponse)
      */
     public void findStaticResource(String path, HttpServletRequest request, HttpServletResponse response)
-            throws IOException {
+        throws IOException {
         String name = cleanupPath(path);
         for (String pathPrefix : pathPrefixes) {
             URL resourceUrl = findResource(buildPath(name, pathPrefix));
@@ -293,7 +306,7 @@ public class DefaultStaticContentLoader implements StaticContentLoader {
     }
 
     /**
-     * @param name resource name
+     * @param name          resource name
      * @param packagePrefix The package prefix to use to locate the resource
      * @return full path
      * @throws UnsupportedEncodingException If there is a encoding problem
@@ -310,7 +323,6 @@ public class DefaultStaticContentLoader implements StaticContentLoader {
     }
 
 
-
     /**
      * Determine the content type for the resource name.
      *
@@ -342,12 +354,9 @@ public class DefaultStaticContentLoader implements StaticContentLoader {
     /**
      * Copy bytes from the input stream to the output stream.
      *
-     * @param input
-     *            The input stream
-     * @param output
-     *            The output stream
-     * @throws IOException
-     *             If anything goes wrong
+     * @param input  The input stream
+     * @param output The output stream
+     * @throws IOException If anything goes wrong
      */
     protected void copy(InputStream input, OutputStream output) throws IOException {
         final byte[] buffer = new byte[4096];
@@ -359,15 +368,18 @@ public class DefaultStaticContentLoader implements StaticContentLoader {
     }
 
     public boolean canHandle(String resourcePath) {
-        return serveStatic && (resourcePath.startsWith("/struts/") || resourcePath.startsWith("/static/"));
+        return serveStatic && resourcePath.startsWith(staticContentPath + "/");
     }
 
     /**
      * @param path requested path
-     * @return path without leading "/struts" or "/static"
+     * @return path without leading {@link #staticContentPath}
      */
     protected String cleanupPath(String path) {
-        //path will start with "/struts" or "/static", remove them
-        return path.substring(7);
+        if (path.startsWith(staticContentPath)) {
+            return path.substring(staticContentPath.length());
+        } else {
+            return path;
+        }
     }
 }
diff --git a/core/src/main/java/org/apache/struts2/dispatcher/StaticContentLoader.java b/core/src/main/java/org/apache/struts2/dispatcher/StaticContentLoader.java
index 7859702..608fdb7 100644
--- a/core/src/main/java/org/apache/struts2/dispatcher/StaticContentLoader.java
+++ b/core/src/main/java/org/apache/struts2/dispatcher/StaticContentLoader.java
@@ -39,12 +39,12 @@ public interface StaticContentLoader {
      * @param path Requested resource path
      * @return true if this loader is able to load this type of resource, false otherwise
      */
-    public boolean canHandle(String path);
+    boolean canHandle(String path);
 
     /**
      * @param filterConfig The filter configuration
      */
-    public abstract void setHostConfig(HostConfig filterConfig);
+    void setHostConfig(HostConfig filterConfig);
 
     /**
      * Locate a static resource and copy directly to the response, setting the
@@ -55,7 +55,6 @@ public interface StaticContentLoader {
      * @param response The response
      * @throws IOException If anything goes wrong
      */
-    public abstract void findStaticResource(String path, HttpServletRequest request, HttpServletResponse response)
-            throws IOException;
+    void findStaticResource(String path, HttpServletRequest request, HttpServletResponse response) throws IOException;
 
 }
diff --git a/core/src/main/resources/org/apache/struts2/default.properties b/core/src/main/resources/org/apache/struts2/default.properties
index 1bbe20c..60819c6 100644
--- a/core/src/main/resources/org/apache/struts2/default.properties
+++ b/core/src/main/resources/org/apache/struts2/default.properties
@@ -147,6 +147,9 @@ struts.ui.theme.expansion.token=~~~
 #sets the default template type. Either ftl, vm, or jsp
 struts.ui.templateSuffix=ftl
 
+### A path from which a static content is served in case of tags
+struts.ui.staticContentPath=/static
+
 ### Configuration reloading
 ### This will cause the configuration to reload struts.xml when it is changed
 ### struts.configuration.xml.reload=false
diff --git a/core/src/main/resources/template/css_xhtml/form-validate.ftl b/core/src/main/resources/template/css_xhtml/form-validate.ftl
index f1b2053..a45aa71 100644
--- a/core/src/main/resources/template/css_xhtml/form-validate.ftl
+++ b/core/src/main/resources/template/css_xhtml/form-validate.ftl
@@ -19,7 +19,7 @@
  */
 -->
 <#if parameters.validate!false == true>
-<script type="text/javascript" src="${base}/struts/css_xhtml/validation.js"></script>
+<script type="text/javascript" src="${base}${parameters.staticContentPath}/css_xhtml/validation.js"></script>
     <#if parameters.onsubmit??>
         ${tag.addParameter('onsubmit', "${parameters.onsubmit}; return validateForm_${parameters.id}();")}
     <#else>
diff --git a/core/src/main/resources/template/css_xhtml/head.ftl b/core/src/main/resources/template/css_xhtml/head.ftl
index d30a25a..7d493e8 100644
--- a/core/src/main/resources/template/css_xhtml/head.ftl
+++ b/core/src/main/resources/template/css_xhtml/head.ftl
@@ -18,5 +18,5 @@
  * under the License.
  */
 -->
-<link <#include "/${parameters.templateDir}/simple/nonce.ftl" /> rel="stylesheet" href="<@s.url value='/struts/css_xhtml/styles.css' includeParams='none' encode='false' />" type="text/css" />
+<link <#include "/${parameters.templateDir}/simple/nonce.ftl" /> rel="stylesheet" href="<@s.url value='${parameters.staticContentPath}/css_xhtml/styles.css' includeParams='none' encode='false' />" type="text/css" />
 <#include "/${parameters.templateDir}/simple/head.ftl" />
diff --git a/core/src/main/resources/template/simple/form-close-tooltips.ftl b/core/src/main/resources/template/simple/form-close-tooltips.ftl
index ac3a6da..21e25a4 100644
--- a/core/src/main/resources/template/simple/form-close-tooltips.ftl
+++ b/core/src/main/resources/template/simple/form-close-tooltips.ftl
@@ -24,7 +24,7 @@
 --><#t/>
 <#if (parameters.hasTooltip!false)><#t/>
 	<#lt/><!-- javascript that is needed for tooltips -->
-	<#lt/><script type="text/javascript" src='<@s.url value="/struts/domTT.js" includeParams="none" encode="false" />' <#include "/${parameters.templateDir}/simple/nonce.ftl" /> > </script>
-	<#lt/><link rel="stylesheet" type="text/css" href="<@s.url value="/struts/domTT.css" includeParams="none" encode="false" />" <#include "/${parameters.templateDir}/simple/nonce.ftl" /> />
+	<#lt/><script type="text/javascript" src='<@s.url value="${parameters.staticContentPath}/domTT.js" includeParams="none" encode="false" />' <#include "/${parameters.templateDir}/simple/nonce.ftl" /> > </script>
+	<#lt/><link rel="stylesheet" type="text/css" href="<@s.url value="${parameters.staticContentPath}/domTT.css" includeParams="none" encode="false" />" <#include "/${parameters.templateDir}/simple/nonce.ftl" /> />
 	
 </#if><#t/>
\ No newline at end of file
diff --git a/core/src/main/resources/template/simple/head.ftl b/core/src/main/resources/template/simple/head.ftl
index 3004715..359d7bf 100644
--- a/core/src/main/resources/template/simple/head.ftl
+++ b/core/src/main/resources/template/simple/head.ftl
@@ -18,4 +18,4 @@
  * under the License.
  */
 -->
-<script src="${base}/struts/utils.js" type="text/javascript" <#include "/${parameters.templateDir}/simple/nonce.ftl" /> ></script>
\ No newline at end of file
+<script src="${base}${parameters.staticContentPath}/utils.js" type="text/javascript" <#include "/${parameters.templateDir}/simple/nonce.ftl" /> ></script>
\ No newline at end of file
diff --git a/core/src/main/resources/template/simple/inputtransferselect.ftl b/core/src/main/resources/template/simple/inputtransferselect.ftl
index dae1a07..a9258dd 100644
--- a/core/src/main/resources/template/simple/inputtransferselect.ftl
+++ b/core/src/main/resources/template/simple/inputtransferselect.ftl
@@ -19,7 +19,7 @@
  */
 -->
 <#if !stack.findValue("#inputtransferselect_js_included")??><#t/>
-	<script type="text/javascript" src="<@s.url value="/struts/inputtransferselect.js" encode='false' includeParams='none'/>" <#include "/${parameters.templateDir}/simple/nonce.ftl" /> ></script>
+	<script type="text/javascript" src="<@s.url value="${parameters.staticContentPath}/inputtransferselect.js" encode='false' includeParams='none'/>" <#include "/${parameters.templateDir}/simple/nonce.ftl" /> ></script>
 	<#assign temporaryVariable = stack.setValue("#inputtransferselect_js_included", "true") /><#t/>
 </#if><#t/>
 <table>
diff --git a/core/src/main/resources/template/simple/optiontransferselect.ftl b/core/src/main/resources/template/simple/optiontransferselect.ftl
index 910dc6a..e0d00ee 100644
--- a/core/src/main/resources/template/simple/optiontransferselect.ftl
+++ b/core/src/main/resources/template/simple/optiontransferselect.ftl
@@ -19,7 +19,7 @@
  */
 -->
 <#if !stack.findValue("#optiontransferselect_js_included")??><#t/>
-	<script type="text/javascript" src="<@s.url value="/struts/optiontransferselect.js" encode='false' includeParams='none'/>" <#include "/${parameters.templateDir}/simple/nonce.ftl" /> ></script>
+	<script type="text/javascript" src="<@s.url value="${parameters.staticContentPath}/optiontransferselect.js" encode='false' includeParams='none'/>" <#include "/${parameters.templateDir}/simple/nonce.ftl" /> ></script>
 	<#assign temporaryVariable = stack.setValue("#optiontransferselect_js_included", "true") /><#t/>
 </#if><#t/>
 <table>
diff --git a/core/src/main/resources/template/simple/updownselect.ftl b/core/src/main/resources/template/simple/updownselect.ftl
index 4f57b84..f1185d3 100644
--- a/core/src/main/resources/template/simple/updownselect.ftl
+++ b/core/src/main/resources/template/simple/updownselect.ftl
@@ -19,7 +19,7 @@
  */
 -->
 <#if !stack.findValue("#optiontransferselect_js_included")??><#t/>
-	<script type="text/javascript" src="<@s.url value="/struts/optiontransferselect.js" encode='false' includeParams='none'/>" <#include "/${parameters.templateDir}/simple/nonce.ftl" /> ></script>
+	<script type="text/javascript" src="<@s.url value="${parameters.staticContentPath}/optiontransferselect.js" encode='false' includeParams='none'/>" <#include "/${parameters.templateDir}/simple/nonce.ftl" /> ></script>
 	<#assign temporaryVariable = stack.setValue("#optiontransferselect_js_included", "true") /><#t/>
 </#if><#t/>
 <table>
diff --git a/core/src/main/resources/template/xhtml/form-validate.ftl b/core/src/main/resources/template/xhtml/form-validate.ftl
index 3a67f44..33e8b55 100644
--- a/core/src/main/resources/template/xhtml/form-validate.ftl
+++ b/core/src/main/resources/template/xhtml/form-validate.ftl
@@ -19,7 +19,7 @@
  */
 -->
 <#if parameters.validate!false == true>
-	<script type="text/javascript" src="${base}/struts/xhtml/validation.js" <#include "/${parameters.templateDir}/simple/nonce.ftl" /> ></script>
+	<script type="text/javascript" src="${base}${parameters.staticContentPath}/xhtml/validation.js" <#include "/${parameters.templateDir}/simple/nonce.ftl" /> ></script>
 	<#if parameters.onsubmit??>
 		${tag.addParameter('onsubmit', "${parameters.onsubmit}; return validateForm_${parameters.id?replace('[^a-zA-Z0-9_]', '_', 'r')}();")}
 	<#else>
diff --git a/core/src/main/resources/template/xhtml/head.ftl b/core/src/main/resources/template/xhtml/head.ftl
index 48678f2..7b5bfe0 100644
--- a/core/src/main/resources/template/xhtml/head.ftl
+++ b/core/src/main/resources/template/xhtml/head.ftl
@@ -18,5 +18,5 @@
  * under the License.
  */
 -->
-<link rel="stylesheet" href="<@s.url value='/struts/xhtml/styles.css' includeParams='none' encode='false'/>" type="text/css" <#include "/${parameters.templateDir}/simple/nonce.ftl" /> />
+<link rel="stylesheet" href="<@s.url value='${parameters.staticContentPath}/xhtml/styles.css' includeParams='none' encode='false'/>" type="text/css" <#include "/${parameters.templateDir}/simple/nonce.ftl" /> />
 <#include "/${parameters.templateDir}/simple/head.ftl" />
diff --git a/core/src/main/resources/template/xhtml/tooltip.ftl b/core/src/main/resources/template/xhtml/tooltip.ftl
index d0b35e7..faa69f6 100644
--- a/core/src/main/resources/template/xhtml/tooltip.ftl
+++ b/core/src/main/resources/template/xhtml/tooltip.ftl
@@ -23,7 +23,7 @@
       <#if parameters.tooltipIconPath??><#t/>
       	src='<@s.url value="${parameters.tooltipIconPath}" includeParams="none" encode="false" />'
       <#else><#t/>
-      	src='<@s.url value="/struts/tooltip.gif" includeParams="none" encode="false" />'
+      	src='<@s.url value="${parameters.staticContentPath}/tooltip.gif" includeParams="none" encode="false" />'
       </#if><#t/>
       <#if (parameters.jsTooltipEnabled!'false') == 'true'>
           onmouseover="domTT_activate(this, event, 'content', '<#outputformat 'JavaScript'>${parameters.tooltip}</#outputformat>'<#t/>
diff --git a/core/src/test/java/org/apache/struts2/dispatcher/DefaultStaticContentLoaderTest.java b/core/src/test/java/org/apache/struts2/dispatcher/DefaultStaticContentLoaderTest.java
index 8f8eda1..d0e93da 100644
--- a/core/src/test/java/org/apache/struts2/dispatcher/DefaultStaticContentLoaderTest.java
+++ b/core/src/test/java/org/apache/struts2/dispatcher/DefaultStaticContentLoaderTest.java
@@ -103,13 +103,14 @@ public class DefaultStaticContentLoaderTest extends StrutsInternalTestCase {
     }
 
     protected void setUp() {
-        requestMock = (HttpServletRequest) createMock(HttpServletRequest.class);
-        responseMock = (HttpServletResponse) createMock(HttpServletResponse.class);
-        hostConfigMock = (HostConfig) createMock(HostConfig.class);
+        requestMock = createMock(HttpServletRequest.class);
+        responseMock = createMock(HttpServletResponse.class);
+        hostConfigMock = createMock(HostConfig.class);
         expect(hostConfigMock.getInitParameter("packages")).andStubReturn(null);
         expect(hostConfigMock.getInitParameter("loggerFactory")).andStubReturn(null);
         defaultStaticContentLoader = new DefaultStaticContentLoader();
         defaultStaticContentLoader.setHostConfig(hostConfigMock);
         defaultStaticContentLoader.setEncoding("UTF-8");
+        defaultStaticContentLoader.setStaticContentPath("/static");
     }
 }
diff --git a/core/src/test/java/org/apache/struts2/dispatcher/StaticContentLoaderTest.java b/core/src/test/java/org/apache/struts2/dispatcher/StaticContentLoaderTest.java
index c991275..fbcf4e6 100644
--- a/core/src/test/java/org/apache/struts2/dispatcher/StaticContentLoaderTest.java
+++ b/core/src/test/java/org/apache/struts2/dispatcher/StaticContentLoaderTest.java
@@ -39,7 +39,7 @@ public class StaticContentLoaderTest extends TestCase {
     private MockHttpServletResponse res;
 
     public void testCantHandleWithoutServingStatic() {
-        StaticContentLoader contentLoader = new DefaultStaticContentLoader();
+        DefaultStaticContentLoader contentLoader = new DefaultStaticContentLoader();
 
         assertFalse(contentLoader.canHandle("/static/test1.css"));
         assertFalse(contentLoader.canHandle("/struts/test1.css"));
@@ -49,14 +49,15 @@ public class StaticContentLoaderTest extends TestCase {
     public void testCanHandle() {
         DefaultStaticContentLoader contentLoader = new DefaultStaticContentLoader();
         contentLoader.setServeStaticContent("true");
+        contentLoader.setStaticContentPath("/static");
 
         assertTrue(contentLoader.canHandle("/static/test1.css"));
-        assertTrue(contentLoader.canHandle("/struts/test1.css"));
+        assertFalse(contentLoader.canHandle("/struts/test1.css"));
         assertFalse(contentLoader.canHandle("test1.css"));
     }
 
-    public void testValidRersources() throws IOException {
-        contentLoader.findStaticResource("/struts/resource.css", req, res);
+    public void testValidResources() throws IOException {
+        contentLoader.findStaticResource("/static/resource.css", req, res);
         assertTrue(res.getContentAsString().contains("color: red;"));
     }
 
@@ -67,25 +68,25 @@ public class StaticContentLoaderTest extends TestCase {
     }
 
     public void testInvalidRersources2() throws IOException {
-        contentLoader.findStaticResource("/struts/..", req, res);
+        contentLoader.findStaticResource("/static/..", req, res);
         assertEquals(HttpServletResponse.SC_NOT_FOUND, res.getStatus());
         assertEquals(0, res.getContentLength());
     }
 
     public void testInvalidRersources3() throws IOException {
-        contentLoader.findStaticResource("/struts/../othertest.properties", req, res);
+        contentLoader.findStaticResource("/static/../othertest.properties", req, res);
         assertEquals(HttpServletResponse.SC_NOT_FOUND, res.getStatus());
         assertEquals(0, res.getContentLength());
     }
 
     public void testInvalidRersources4() throws IOException {
-        contentLoader.findStaticResource("/struts/..%252f", req, res);
+        contentLoader.findStaticResource("/static/..%252f", req, res);
         assertEquals(HttpServletResponse.SC_NOT_FOUND, res.getStatus());
         assertEquals(0, res.getContentLength());
     }
 
     public void testInvalidRersources5() throws IOException {
-        contentLoader.findStaticResource("/struts/..%252fothertest.properties", req, res);
+        contentLoader.findStaticResource("/static/..%252fothertest.properties", req, res);
         assertEquals(HttpServletResponse.SC_NOT_FOUND, res.getStatus());
         assertEquals(0, res.getContentLength());
     }
@@ -95,6 +96,7 @@ public class StaticContentLoaderTest extends TestCase {
         super.setUp();
 
         this.contentLoader = new DefaultStaticContentLoader();
+        this.contentLoader.setStaticContentPath("/static");
         MockServletContext servletContext = new MockServletContext();
         req = new MockHttpServletRequest(servletContext);
         res = new MockHttpServletResponse();
diff --git a/core/src/test/java/org/apache/struts2/dispatcher/StrutsPrepareAndExecuteFilterIntegrationTest.java b/core/src/test/java/org/apache/struts2/dispatcher/StrutsPrepareAndExecuteFilterIntegrationTest.java
index 7bc46ed..a5419cd 100644
--- a/core/src/test/java/org/apache/struts2/dispatcher/StrutsPrepareAndExecuteFilterIntegrationTest.java
+++ b/core/src/test/java/org/apache/struts2/dispatcher/StrutsPrepareAndExecuteFilterIntegrationTest.java
@@ -179,7 +179,7 @@ public class StrutsPrepareAndExecuteFilterIntegrationTest extends TestCase {
             }
         };
 
-        request.setRequestURI("/struts/utils.js");
+        request.setRequestURI("/static/utils.js");
         StrutsPrepareAndExecuteFilter filter = new StrutsPrepareAndExecuteFilter();
         filter.init(filterConfig);
         filter.doFilter(request, response, filterChain);
diff --git a/core/src/test/java/org/apache/struts2/dispatcher/TwoFilterIntegrationTest.java b/core/src/test/java/org/apache/struts2/dispatcher/TwoFilterIntegrationTest.java
index b432a8d..edc88ba 100644
--- a/core/src/test/java/org/apache/struts2/dispatcher/TwoFilterIntegrationTest.java
+++ b/core/src/test/java/org/apache/struts2/dispatcher/TwoFilterIntegrationTest.java
@@ -79,7 +79,7 @@ public class TwoFilterIntegrationTest extends TestCase {
     }
 
     public void testStaticExecute() throws ServletException, IOException {
-        MockHttpServletResponse response = run("/struts/utils.js", filterPrepare, filterExecute, failFilter);
+        MockHttpServletResponse response = run("/static/utils.js", filterPrepare, filterExecute, failFilter);
         assertEquals(200, response.getStatus());
         assertTrue(response.getContentAsString().contains("StrutsUtils"));
     }
diff --git a/core/src/test/java/org/apache/struts2/views/jsp/ui/TooltipTest.java b/core/src/test/java/org/apache/struts2/views/jsp/ui/TooltipTest.java
index 50d2bc5..8c8d8e1 100644
--- a/core/src/test/java/org/apache/struts2/views/jsp/ui/TooltipTest.java
+++ b/core/src/test/java/org/apache/struts2/views/jsp/ui/TooltipTest.java
@@ -52,7 +52,7 @@ public class TooltipTest extends AbstractUITagTest {
         tag.setTooltip("myTooltip");
         tag.setTooltipConfig(
                 "#{" +
-                        "'tooltipIcon':'/struts/tooltip/myTooltip.gif', " +
+                        "'tooltipIcon':'/static/tooltip/myTooltip.gif', " +
                         "'tooltipDelay':'500', " +
                         "'jsTooltipEnabled':'true' "+
                         "}"
@@ -86,7 +86,7 @@ public class TooltipTest extends AbstractUITagTest {
         tag.setTooltip("myTooltip");
         tag.setTooltipConfig(
                 "#{" +
-                        "'tooltipIcon':'/struts/tooltip/myTooltip.gif', " +
+                        "'tooltipIcon':'/static/tooltip/myTooltip.gif', " +
                         "'tooltipDelay':'500', " +
                         "'jsTooltipEnabled':'false' "+
                         "}"
@@ -119,7 +119,7 @@ public class TooltipTest extends AbstractUITagTest {
 
         //same parameters as the OGNL map configuration, output must be the same
         tag.setTooltip("myTooltip");
-        tag.setTooltipIconPath("/struts/tooltip/myTooltip.gif");
+        tag.setTooltipIconPath("/static/tooltip/myTooltip.gif");
         tag.setTooltipDelay("500");
         tag.setJavascriptTooltip("true");
        
@@ -142,7 +142,7 @@ public class TooltipTest extends AbstractUITagTest {
 
         formTag.setTooltipConfig(
                 "#{" +
-                "'tooltipIcon':'/struts/tooltip/myTooltip.gif', " +
+                "'tooltipIcon':'/static/tooltip/myTooltip.gif', " +
                 "'tooltipDelay':'500', " +
                 "'jsTooltipEnabled':'true' "+
                 "}"
@@ -174,7 +174,7 @@ public class TooltipTest extends AbstractUITagTest {
 
         // same parameters as the OGNL map configuration, output must be the same
         formTag.setTooltip("myTooltip");
-        formTag.setTooltipIconPath("/struts/tooltip/myTooltip.gif");
+        formTag.setTooltipIconPath("/static/tooltip/myTooltip.gif");
         formTag.setTooltipDelay("500");
         formTag.setJavascriptTooltip("true");
 
@@ -204,7 +204,7 @@ public class TooltipTest extends AbstractUITagTest {
 
         formTag.setTooltipConfig(
                 "#{" +
-                "'tooltipIcon':'/struts/tooltip/myTooltip.gif', " +
+                "'tooltipIcon':'/static/tooltip/myTooltip.gif', " +
                 "'tooltipDelay':'500', " +
                 "'jsTooltipEnabled':'true' "+
                 "}"
@@ -219,7 +219,7 @@ public class TooltipTest extends AbstractUITagTest {
         tag.setTooltip("myTooltip");
         tag.setTooltipConfig(
                 "#{" +
-                "'tooltipIcon':'/struts/tooltip/myTooltip2.gif', " +
+                "'tooltipIcon':'/static/tooltip/myTooltip2.gif', " +
                 "'tooltipDelay':'5000' " +
                 "}"
         );
@@ -242,7 +242,7 @@ public class TooltipTest extends AbstractUITagTest {
 
         // same parameters as the OGNL map configuration, output must be the same
         formTag.setTooltip("myTooltip");
-        formTag.setTooltipIconPath("/struts/tooltip/myTooltip.gif");
+        formTag.setTooltipIconPath("/static/tooltip/myTooltip.gif");
         formTag.setTooltipDelay("500");
         formTag.setJavascriptTooltip("true");
 
@@ -255,7 +255,7 @@ public class TooltipTest extends AbstractUITagTest {
 
         //same parameters as the OGNL map configuration, output must be the same
         tag.setTooltip("myTooltip");
-        tag.setTooltipIconPath("/struts/tooltip/myTooltip2.gif");
+        tag.setTooltipIconPath("/static/tooltip/myTooltip2.gif");
         tag.setTooltipDelay("5000");
         tag.setJavascriptTooltip("true");
 
@@ -280,7 +280,7 @@ public class TooltipTest extends AbstractUITagTest {
         formParamTag.setName("tooltipConfig");
         formParamTag.setValue(
                 "#{" +
-                "'tooltipIcon':'/struts/tooltip/myTooltip.gif', " +
+                "'tooltipIcon':'/static/tooltip/myTooltip.gif', " +
                 "'tooltipDelay':'500', " +
                 "'jsTooltipEnabled':'true' "+
                 "}"
@@ -298,7 +298,7 @@ public class TooltipTest extends AbstractUITagTest {
         textFieldParamTag.setName("tooltipConfig");
         textFieldParamTag.setValue(
                 "#{" +
-                "'tooltipIcon':'/struts/tooltip/myTooltip2.gif', " +
+                "'tooltipIcon':'/static/tooltip/myTooltip2.gif', " +
                 "'tooltipDelay':'5000' "+
                 "}"
         );
@@ -330,7 +330,7 @@ public class TooltipTest extends AbstractUITagTest {
         formParamTag.setName("tooltipConfig");
         StrutsMockBodyContent bodyContent = new StrutsMockBodyContent(new MockJspWriter());
         bodyContent.setString(
-                "tooltipIcon=/struts/tooltip/myTooltip.gif| " +
+                "tooltipIcon=/static/tooltip/myTooltip.gif| " +
                 "tooltipDelay=500| " +
                 "jsTooltipEnabled=true "
         );
@@ -348,7 +348,7 @@ public class TooltipTest extends AbstractUITagTest {
         textFieldParamTag.setName("tooltipConfig");
         StrutsMockBodyContent bodyContent2 = new StrutsMockBodyContent(new MockJspWriter());
         bodyContent2.setString(
-                "tooltipIcon=/struts/tooltip/myTooltip2.gif| " +
+                "tooltipIcon=/static/tooltip/myTooltip2.gif| " +
                 "tooltipDelay=5000 "
         );
         textFieldParamTag.setBodyContent(bodyContent2);
diff --git a/core/src/test/resources/org/apache/struts2/views/jsp/ui/Formtag-11.txt b/core/src/test/resources/org/apache/struts2/views/jsp/ui/Formtag-11.txt
index ca4358a..7a4889c 100644
--- a/core/src/test/resources/org/apache/struts2/views/jsp/ui/Formtag-11.txt
+++ b/core/src/test/resources/org/apache/struts2/views/jsp/ui/Formtag-11.txt
@@ -1,8 +1,8 @@
-<script type="text/javascript" src="/struts/xhtml/validation.js"></script>
+<script type="text/javascript" src="/static/xhtml/validation.js"></script>
 <form id="testAction" name="myForm" onsubmit="submitMe(); return validateForm_testAction();" action="/testAction.action" method="post" enctype="myEncType" title="mytitle" accept-charset="UTF-8" onreset="clearErrorMessages(this);clearErrorLabels(this);">
 <table class="wwFormTable"> <tr>
     <td class="tdLabel"></td>
-    <td class="tdInput">	<script type="text/javascript" src="/struts/optiontransferselect.js"></script>
+    <td class="tdInput">	<script type="text/javascript" src="/static/optiontransferselect.js"></script>
 <table>
 <tr><td>
 <select name="myUpDownSelectTag" size="5" id="testAction_myUpDownSelectTag" multiple="multiple">
diff --git a/core/src/test/resources/org/apache/struts2/views/jsp/ui/Formtag-2.txt b/core/src/test/resources/org/apache/struts2/views/jsp/ui/Formtag-2.txt
index 99ea368..e52e2c0 100644
--- a/core/src/test/resources/org/apache/struts2/views/jsp/ui/Formtag-2.txt
+++ b/core/src/test/resources/org/apache/struts2/views/jsp/ui/Formtag-2.txt
@@ -1,8 +1,8 @@
-<script type="text/javascript" src="/struts/xhtml/validation.js"></script>
+<script type="text/javascript" src="/static/xhtml/validation.js"></script>
 <form id="doubleValidationAction" name="myForm" onsubmit="submitMe(); return validateForm_doubleValidationAction();" action="/doubleValidationAction.action" method="post" enctype="myEncType" title="mytitle" accept-charset="UTF-8" onreset="clearErrorMessages(this);clearErrorLabels(this);">
 <table class="wwFormTable"> <tr>
     <td class="tdLabel"></td>
-    <td class="tdInput">	<script type="text/javascript" src="/struts/optiontransferselect.js"></script>
+    <td class="tdInput">	<script type="text/javascript" src="/static/optiontransferselect.js"></script>
 <table>
 <tr><td>
 <select name="myUpDownSelectTag" size="5" id="doubleValidationAction_myUpDownSelectTag" multiple="multiple">
diff --git a/core/src/test/resources/org/apache/struts2/views/jsp/ui/Formtag-22.txt b/core/src/test/resources/org/apache/struts2/views/jsp/ui/Formtag-22.txt
index c03ae9d..4cc6773 100644
--- a/core/src/test/resources/org/apache/struts2/views/jsp/ui/Formtag-22.txt
+++ b/core/src/test/resources/org/apache/struts2/views/jsp/ui/Formtag-22.txt
@@ -1,8 +1,8 @@
-<script type="text/javascript" src="/struts/xhtml/validation.js"></script>
+<script type="text/javascript" src="/static/xhtml/validation.js"></script>
 <form id="doubleValidationAction" name="myForm" onsubmit="submitMe(); return validateForm_doubleValidationAction();" action="/doubleValidationAction.action" method="post" enctype="myEncType" title="mytitle" accept-charset="UTF-8" onreset="clearErrorMessages(this);clearErrorLabels(this);">
 <table class="wwFormTable"> <tr>
     <td class="tdLabel"></td>
-    <td class="tdInput">	<script type="text/javascript" src="/struts/optiontransferselect.js"></script>
+    <td class="tdInput">	<script type="text/javascript" src="/static/optiontransferselect.js"></script>
 <table>
 <tr><td>
 <select name="myUpDownSelectTag" size="5" id="doubleValidationAction_myUpDownSelectTag" multiple="multiple">
diff --git a/core/src/test/resources/org/apache/struts2/views/jsp/ui/Formtag-24.txt b/core/src/test/resources/org/apache/struts2/views/jsp/ui/Formtag-24.txt
index b6178cd..61c7801 100644
--- a/core/src/test/resources/org/apache/struts2/views/jsp/ui/Formtag-24.txt
+++ b/core/src/test/resources/org/apache/struts2/views/jsp/ui/Formtag-24.txt
@@ -1,8 +1,8 @@
-<script type="text/javascript" src="/struts/xhtml/validation.js"></script>
+<script type="text/javascript" src="/static/xhtml/validation.js"></script>
 <form id="doubleValidationAction" name="myForm" onsubmit="submitMe(); return validateForm_doubleValidationAction();" action="/doubleValidationAction.action" method="post" enctype="myEncType" title="mytitle" accept-charset="UTF-8" onreset="clearErrorMessages(this);clearErrorLabels(this);">
 <table class="wwFormTable"> <tr>
     <td class="tdLabel"></td>
-    <td class="tdInput">	<script type="text/javascript" src="/struts/optiontransferselect.js"></script>
+    <td class="tdInput">	<script type="text/javascript" src="/static/optiontransferselect.js"></script>
 <table>
 <tr><td>
 <select name="myUpDownSelectTag" size="5" id="doubleValidationAction_myUpDownSelectTag" multiple="multiple">
diff --git a/core/src/test/resources/org/apache/struts2/views/jsp/ui/Formtag-6.txt b/core/src/test/resources/org/apache/struts2/views/jsp/ui/Formtag-6.txt
index 2c62222..3ffab94 100644
--- a/core/src/test/resources/org/apache/struts2/views/jsp/ui/Formtag-6.txt
+++ b/core/src/test/resources/org/apache/struts2/views/jsp/ui/Formtag-6.txt
@@ -1,7 +1,7 @@
 <form id="myAction" name="myForm" onsubmit="submitMe()" action="myAction" method="post" enctype="myEncType" title="mytitle">
 <table class="wwFormTable"> <tr>
     <td class="tdLabel"></td>
-    <td class="tdInput">	<script type="text/javascript" src="/struts/optiontransferselect.js"></script>
+    <td class="tdInput">	<script type="text/javascript" src="/static/optiontransferselect.js"></script>
 <table>
 <tr><td>
 <select name="myUpDownSelectTag" size="5" id="myAction_myUpDownSelectTag" multiple="multiple">
diff --git a/core/src/test/resources/org/apache/struts2/views/jsp/ui/HeadTagTest-1.txt b/core/src/test/resources/org/apache/struts2/views/jsp/ui/HeadTagTest-1.txt
index d9c6359..00dd01f 100644
--- a/core/src/test/resources/org/apache/struts2/views/jsp/ui/HeadTagTest-1.txt
+++ b/core/src/test/resources/org/apache/struts2/views/jsp/ui/HeadTagTest-1.txt
@@ -1,2 +1,2 @@
-<link rel="stylesheet" href="/struts/xhtml/styles.css" type="text/css" nonce="r4nd0m"/>
-<script src="/struts/utils.js" type="text/javascript" nonce="r4nd0m"></script>
\ No newline at end of file
+<link rel="stylesheet" href="/static/xhtml/styles.css" type="text/css" nonce="r4nd0m"/>
+<script src="/static/utils.js" type="text/javascript" nonce="r4nd0m"></script>
\ No newline at end of file
diff --git a/core/src/test/resources/org/apache/struts2/views/jsp/ui/inputtransferselect-1.txt b/core/src/test/resources/org/apache/struts2/views/jsp/ui/inputtransferselect-1.txt
index a73b85a..f3c81d1 100644
--- a/core/src/test/resources/org/apache/struts2/views/jsp/ui/inputtransferselect-1.txt
+++ b/core/src/test/resources/org/apache/struts2/views/jsp/ui/inputtransferselect-1.txt
@@ -1,7 +1,7 @@
 <tr>
   <td class="tdLabel"></td>
   <td class="tdInput">
-  <script type="text/javascript" src="/struts/inputtransferselect.js" nonce="r4nd0m"></script>
+  <script type="text/javascript" src="/static/inputtransferselect.js" nonce="r4nd0m"></script>
   <table>
   <tr><td><input type="text" name="collection_input" id="collection_input"/></td>
       <td class="tdTransferSelect"><inputtype="button"value="-&gt;"onclick="addOption(document.getElementById('collection_input'),document.getElementById('collection'))"/>
diff --git a/core/src/test/resources/org/apache/struts2/views/jsp/ui/optiontransferselect-1.txt b/core/src/test/resources/org/apache/struts2/views/jsp/ui/optiontransferselect-1.txt
index 2ee3705..f168865 100644
--- a/core/src/test/resources/org/apache/struts2/views/jsp/ui/optiontransferselect-1.txt
+++ b/core/src/test/resources/org/apache/struts2/views/jsp/ui/optiontransferselect-1.txt
@@ -1,7 +1,7 @@
 <tr> 
 <td class="tdLabel"></td> 
 <td class="tdInput">
-<script type="text/javascript" src="/struts/optiontransferselect.js" nonce="r4nd0m"></script>
+<script type="text/javascript" src="/static/optiontransferselect.js" nonce="r4nd0m"></script>
 <table>
 <tr>
 <td>
diff --git a/core/src/test/resources/org/apache/struts2/views/jsp/ui/optiontransferselect-2.txt b/core/src/test/resources/org/apache/struts2/views/jsp/ui/optiontransferselect-2.txt
index 2713cec..359475c 100644
--- a/core/src/test/resources/org/apache/struts2/views/jsp/ui/optiontransferselect-2.txt
+++ b/core/src/test/resources/org/apache/struts2/views/jsp/ui/optiontransferselect-2.txt
@@ -1,7 +1,7 @@
 <tr> 
 <td class="tdLabel"></td>
 <td class="tdInput">
-<script type="text/javascript" src="/struts/optiontransferselect.js"></script>
+<script type="text/javascript" src="/static/optiontransferselect.js"></script>
 <table>
 <tr>
 <td>
diff --git a/core/src/test/resources/org/apache/struts2/views/jsp/ui/optiontransferselect-3.txt b/core/src/test/resources/org/apache/struts2/views/jsp/ui/optiontransferselect-3.txt
index fee9003..46724ab 100644
--- a/core/src/test/resources/org/apache/struts2/views/jsp/ui/optiontransferselect-3.txt
+++ b/core/src/test/resources/org/apache/struts2/views/jsp/ui/optiontransferselect-3.txt
@@ -1,7 +1,7 @@
 <tr> 
 <td class="tdLabel"></td>
 <td class="tdInput">
-<script type="text/javascript" src="/struts/optiontransferselect.js"></script>
+<script type="text/javascript" src="/static/optiontransferselect.js"></script>
 <table>
 <tr>
 <td>
diff --git a/core/src/test/resources/org/apache/struts2/views/jsp/ui/optiontransferselect-4.txt b/core/src/test/resources/org/apache/struts2/views/jsp/ui/optiontransferselect-4.txt
index 61668b2..39d5b1b 100644
--- a/core/src/test/resources/org/apache/struts2/views/jsp/ui/optiontransferselect-4.txt
+++ b/core/src/test/resources/org/apache/struts2/views/jsp/ui/optiontransferselect-4.txt
@@ -1,7 +1,7 @@
 <tr> 
 <td class="tdLabel"></td>
 <td class="tdInput">
-<script type="text/javascript" src="/struts/optiontransferselect.js"></script>
+<script type="text/javascript" src="/static/optiontransferselect.js"></script>
 <table>
 <tr>
 <td>
diff --git a/core/src/test/resources/org/apache/struts2/views/jsp/ui/optiontransferselect-5.txt b/core/src/test/resources/org/apache/struts2/views/jsp/ui/optiontransferselect-5.txt
index dc0057f..fb0c979 100644
--- a/core/src/test/resources/org/apache/struts2/views/jsp/ui/optiontransferselect-5.txt
+++ b/core/src/test/resources/org/apache/struts2/views/jsp/ui/optiontransferselect-5.txt
@@ -1,7 +1,7 @@
 <tr> 
 <td class="tdLabel"></td> 
 <td class="tdInput">
-<script type="text/javascript" src="/struts/optiontransferselect.js"></script>
+<script type="text/javascript" src="/static/optiontransferselect.js"></script>
 <table>
 <tr>
 <td>
diff --git a/core/src/test/resources/org/apache/struts2/views/jsp/ui/optiontransferselect-6.txt b/core/src/test/resources/org/apache/struts2/views/jsp/ui/optiontransferselect-6.txt
index ade6e34..68b99d0 100644
--- a/core/src/test/resources/org/apache/struts2/views/jsp/ui/optiontransferselect-6.txt
+++ b/core/src/test/resources/org/apache/struts2/views/jsp/ui/optiontransferselect-6.txt
@@ -1,7 +1,7 @@
 <tr> 
 <td class="tdLabel"></td>
 <td class="tdInput">
-<script type="text/javascript" src="/struts/optiontransferselect.js"></script>
+<script type="text/javascript" src="/static/optiontransferselect.js"></script>
 <table>
 <tr>
 <td>
diff --git a/core/src/test/resources/org/apache/struts2/views/jsp/ui/optiontransferselect-7.txt b/core/src/test/resources/org/apache/struts2/views/jsp/ui/optiontransferselect-7.txt
index 9becafc..270464f 100644
--- a/core/src/test/resources/org/apache/struts2/views/jsp/ui/optiontransferselect-7.txt
+++ b/core/src/test/resources/org/apache/struts2/views/jsp/ui/optiontransferselect-7.txt
@@ -1,7 +1,7 @@
 <tr> 
 <td class="tdLabel"></td>
 <td class="tdInput">
-<script type="text/javascript" src="/struts/optiontransferselect.js"></script>
+<script type="text/javascript" src="/static/optiontransferselect.js"></script>
 <table>
 <tr>
 <td>
diff --git a/core/src/test/resources/org/apache/struts2/views/jsp/ui/tooltip-1.txt b/core/src/test/resources/org/apache/struts2/views/jsp/ui/tooltip-1.txt
index 8394cb5..80b16d0 100644
--- a/core/src/test/resources/org/apache/struts2/views/jsp/ui/tooltip-1.txt
+++ b/core/src/test/resources/org/apache/struts2/views/jsp/ui/tooltip-1.txt
@@ -4,7 +4,7 @@
 			<td class="tdLabel">
 				<labelfor="myId"class="label">
 					MyLabel:<img
-								src='/struts/tooltip/myTooltip.gif'
+								src='/static/tooltip/myTooltip.gif'
 								onmouseover="domTT_activate(this,event,'content','myTooltip','delay','500','styleClass','StrutsTTClassic')"/>
 				</label>
 			</td>
@@ -15,7 +15,7 @@
 	</table>
 </form>
 <!--javascript that is needed for tooltips-->
-<script type="text/javascript" src='/struts/domTT.js'></script>
-<link rel="stylesheet" type="text/css" href="/struts/domTT.css"/>
+<script type="text/javascript" src='/static/domTT.js'></script>
+<link rel="stylesheet" type="text/css" href="/static/domTT.css"/>
 
 
diff --git a/core/src/test/resources/org/apache/struts2/views/jsp/ui/tooltip-2.txt b/core/src/test/resources/org/apache/struts2/views/jsp/ui/tooltip-2.txt
index 596854e..88a298f 100644
--- a/core/src/test/resources/org/apache/struts2/views/jsp/ui/tooltip-2.txt
+++ b/core/src/test/resources/org/apache/struts2/views/jsp/ui/tooltip-2.txt
@@ -4,7 +4,7 @@
 			<td class="tdLabel">
 				<labelfor="myId"class="label">
 					MyLabel:<img
-								src='/struts/tooltip/myTooltip.gif'
+								src='/static/tooltip/myTooltip.gif'
 								onmouseover="domTT_activate(this,event,'content','myTooltip','delay','500','styleClass','StrutsTTClassic')"/>
 				</label>
 			</td>
@@ -15,5 +15,5 @@
 	</table>
 </form>
 <!--javascript that is needed for tooltips-->
-<script type="text/javascript" src='/struts/domTT.js'></script>
-<link rel="stylesheet" type="text/css" href="/struts/domTT.css"/>
\ No newline at end of file
+<script type="text/javascript" src='/static/domTT.js'></script>
+<link rel="stylesheet" type="text/css" href="/static/domTT.css"/>
\ No newline at end of file
diff --git a/core/src/test/resources/org/apache/struts2/views/jsp/ui/tooltip-3.txt b/core/src/test/resources/org/apache/struts2/views/jsp/ui/tooltip-3.txt
index e488564..2c1e49b 100644
--- a/core/src/test/resources/org/apache/struts2/views/jsp/ui/tooltip-3.txt
+++ b/core/src/test/resources/org/apache/struts2/views/jsp/ui/tooltip-3.txt
@@ -4,7 +4,7 @@
 			<td class="tdLabel">
 				<labelfor="myId"class="label">
 					MyLabel:<img
-								src='/struts/tooltip/myTooltip2.gif'
+								src='/static/tooltip/myTooltip2.gif'
 								onmouseover="domTT_activate(this,event,'content','myTooltip','delay','5000','styleClass','StrutsTTClassic')"/>
 				</label>
 			</td>
@@ -16,6 +16,6 @@
 </form>
 
 <!--javascript that is needed for tooltips-->
-<script type="text/javascript" src='/struts/domTT.js'></script>
-<link rel="stylesheet" type="text/css" href="/struts/domTT.css"/>
+<script type="text/javascript" src='/static/domTT.js'></script>
+<link rel="stylesheet" type="text/css" href="/static/domTT.css"/>
 
diff --git a/core/src/test/resources/org/apache/struts2/views/jsp/ui/tooltip-4.txt b/core/src/test/resources/org/apache/struts2/views/jsp/ui/tooltip-4.txt
index f8aad53..dcdd038 100644
--- a/core/src/test/resources/org/apache/struts2/views/jsp/ui/tooltip-4.txt
+++ b/core/src/test/resources/org/apache/struts2/views/jsp/ui/tooltip-4.txt
@@ -4,7 +4,7 @@
 			<td class="tdLabel">
 				<labelfor="myId"class="label">
 					MyLabel:<img
-								src='/struts/tooltip/myTooltip.gif'
+								src='/static/tooltip/myTooltip.gif'
 								title="myTooltip" alt="myTooltip" />
 				</label>
 			</td>
diff --git a/core/src/test/resources/org/apache/struts2/views/jsp/ui/updownselecttag-1.txt b/core/src/test/resources/org/apache/struts2/views/jsp/ui/updownselecttag-1.txt
index 2f0974e..3d35427 100644
--- a/core/src/test/resources/org/apache/struts2/views/jsp/ui/updownselecttag-1.txt
+++ b/core/src/test/resources/org/apache/struts2/views/jsp/ui/updownselecttag-1.txt
@@ -1,5 +1,5 @@
 <tr> <td class="tdLabel"></td> <td class="tdInput">
-<script type="text/javascript" src="/struts/optiontransferselect.js"></script>
+<script type="text/javascript" src="/static/optiontransferselect.js"></script>
 <table>
 <tr><td>
 <select name="myName" size="5" id="myId" multiple="multiple">
diff --git a/core/src/test/resources/org/apache/struts2/views/jsp/ui/updownselecttag-10.txt b/core/src/test/resources/org/apache/struts2/views/jsp/ui/updownselecttag-10.txt
index b98ee46..74e0ab5 100644
--- a/core/src/test/resources/org/apache/struts2/views/jsp/ui/updownselecttag-10.txt
+++ b/core/src/test/resources/org/apache/struts2/views/jsp/ui/updownselecttag-10.txt
@@ -1,5 +1,5 @@
 <tr> <td class="tdLabel"></td> <td class="tdInput">
-<script type="text/javascript" src="/struts/optiontransferselect.js"></script>
+<script type="text/javascript" src="/static/optiontransferselect.js"></script>
 <table>
 <tr><td>
 <select name="myName" size="5" id="myId" multiple="multiple">
diff --git a/core/src/test/resources/org/apache/struts2/views/jsp/ui/updownselecttag-11.txt b/core/src/test/resources/org/apache/struts2/views/jsp/ui/updownselecttag-11.txt
index 593a7b9..3f68bc6 100644
--- a/core/src/test/resources/org/apache/struts2/views/jsp/ui/updownselecttag-11.txt
+++ b/core/src/test/resources/org/apache/struts2/views/jsp/ui/updownselecttag-11.txt
@@ -1,5 +1,5 @@
 <tr> <td class="tdLabel"></td> <td class="tdInput">
-<script type="text/javascript" src="/struts/optiontransferselect.js"></script>
+<script type="text/javascript" src="/static/optiontransferselect.js"></script>
 <table>
 <tr><td>
 <select name="myName" size="5" id="myId" multiple="multiple">
diff --git a/core/src/test/resources/org/apache/struts2/views/jsp/ui/updownselecttag-2.txt b/core/src/test/resources/org/apache/struts2/views/jsp/ui/updownselecttag-2.txt
index 0f8944b..f890aed 100644
--- a/core/src/test/resources/org/apache/struts2/views/jsp/ui/updownselecttag-2.txt
+++ b/core/src/test/resources/org/apache/struts2/views/jsp/ui/updownselecttag-2.txt
@@ -1,5 +1,5 @@
 <tr> <td class="tdLabel"></td> <td class="tdInput">
-<script type="text/javascript" src="/struts/optiontransferselect.js" nonce="r4nd0m"></script>
+<script type="text/javascript" src="/static/optiontransferselect.js" nonce="r4nd0m"></script>
 <table>
 <tr><td>
 <select name="myName" size="5" id="myId" multiple="multiple">
diff --git a/core/src/test/resources/org/apache/struts2/views/jsp/ui/updownselecttag-3.txt b/core/src/test/resources/org/apache/struts2/views/jsp/ui/updownselecttag-3.txt
index 40d57d5..004b42a 100644
--- a/core/src/test/resources/org/apache/struts2/views/jsp/ui/updownselecttag-3.txt
+++ b/core/src/test/resources/org/apache/struts2/views/jsp/ui/updownselecttag-3.txt
@@ -1,5 +1,5 @@
 <tr> <td class="tdLabel"></td> <td class="tdInput">
-<script type="text/javascript" src="/struts/optiontransferselect.js"></script>
+<script type="text/javascript" src="/static/optiontransferselect.js"></script>
 <table>
 <tr><td>
 <select name="myName" size="5" id="myId" multiple="multiple">
diff --git a/core/src/test/resources/org/apache/struts2/views/jsp/ui/updownselecttag-4.txt b/core/src/test/resources/org/apache/struts2/views/jsp/ui/updownselecttag-4.txt
index 1237d1b..2e54fc1 100644
--- a/core/src/test/resources/org/apache/struts2/views/jsp/ui/updownselecttag-4.txt
+++ b/core/src/test/resources/org/apache/struts2/views/jsp/ui/updownselecttag-4.txt
@@ -1,5 +1,5 @@
 <tr> <td class="tdLabel"></td> <td class="tdInput">
-<script type="text/javascript" src="/struts/optiontransferselect.js"></script>
+<script type="text/javascript" src="/static/optiontransferselect.js"></script>
 <table>
 <tr><td>
 <select name="myName" size="5" id="myId" multiple="multiple">
diff --git a/core/src/test/resources/org/apache/struts2/views/jsp/ui/updownselecttag-5.txt b/core/src/test/resources/org/apache/struts2/views/jsp/ui/updownselecttag-5.txt
index 6a87c21..37629ca 100644
--- a/core/src/test/resources/org/apache/struts2/views/jsp/ui/updownselecttag-5.txt
+++ b/core/src/test/resources/org/apache/struts2/views/jsp/ui/updownselecttag-5.txt
@@ -1,5 +1,5 @@
 <tr> <td class="tdLabel"></td> <td class="tdInput">
-<script type="text/javascript" src="/struts/optiontransferselect.js"></script>
+<script type="text/javascript" src="/static/optiontransferselect.js"></script>
 <table>
 <tr><td>
 <select name="myName" size="5" id="myId" multiple="multiple">
diff --git a/core/src/test/resources/org/apache/struts2/views/jsp/ui/updownselecttag-6.txt b/core/src/test/resources/org/apache/struts2/views/jsp/ui/updownselecttag-6.txt
index 2a8ccd6..c0fbd75 100644
--- a/core/src/test/resources/org/apache/struts2/views/jsp/ui/updownselecttag-6.txt
+++ b/core/src/test/resources/org/apache/struts2/views/jsp/ui/updownselecttag-6.txt
@@ -1,5 +1,5 @@
 <tr> <td class="tdLabel"></td> <td class="tdInput">
-<script type="text/javascript" src="/struts/optiontransferselect.js"></script>
+<script type="text/javascript" src="/static/optiontransferselect.js"></script>
 <table>
 <tr><td>
 <select name="myName" size="5" id="myId" multiple="multiple">
diff --git a/core/src/test/resources/org/apache/struts2/views/jsp/ui/updownselecttag-7.txt b/core/src/test/resources/org/apache/struts2/views/jsp/ui/updownselecttag-7.txt
index 6d6fab9..75f15d7 100644
--- a/core/src/test/resources/org/apache/struts2/views/jsp/ui/updownselecttag-7.txt
+++ b/core/src/test/resources/org/apache/struts2/views/jsp/ui/updownselecttag-7.txt
@@ -1,5 +1,5 @@
 <tr> <td class="tdLabel"></td> <td class="tdInput">
-<script type="text/javascript" src="/struts/optiontransferselect.js"></script>
+<script type="text/javascript" src="/static/optiontransferselect.js"></script>
 <table>
 <tr><td>
 <select name="myName" size="5" id="myId" multiple="multiple">
diff --git a/core/src/test/resources/org/apache/struts2/views/jsp/ui/updownselecttag-8.txt b/core/src/test/resources/org/apache/struts2/views/jsp/ui/updownselecttag-8.txt
index 939b784..90e4e0b 100644
--- a/core/src/test/resources/org/apache/struts2/views/jsp/ui/updownselecttag-8.txt
+++ b/core/src/test/resources/org/apache/struts2/views/jsp/ui/updownselecttag-8.txt
@@ -1,5 +1,5 @@
 <tr> <td class="tdLabel"></td> <td class="tdInput">
-<script type="text/javascript" src="/struts/optiontransferselect.js"></script>
+<script type="text/javascript" src="/static/optiontransferselect.js"></script>
 <table>
 <tr><td>
 <select name="myName" size="5" id="myId" multiple="multiple">
diff --git a/core/src/test/resources/org/apache/struts2/views/jsp/ui/updownselecttag-9.txt b/core/src/test/resources/org/apache/struts2/views/jsp/ui/updownselecttag-9.txt
index bebbd9b..5869c67 100644
--- a/core/src/test/resources/org/apache/struts2/views/jsp/ui/updownselecttag-9.txt
+++ b/core/src/test/resources/org/apache/struts2/views/jsp/ui/updownselecttag-9.txt
@@ -1,5 +1,5 @@
 <tr> <td class="tdLabel"></td> <td class="tdInput">
-<script type="text/javascript" src="/struts/optiontransferselect.js"></script>
+<script type="text/javascript" src="/static/optiontransferselect.js"></script>
 <table>
 <tr><td>
 <select name="myName" size="5" id="myId" multiple="multiple">
diff --git a/plugins/javatemplates/src/main/java/org/apache/struts2/views/java/simple/HeadHandler.java b/plugins/javatemplates/src/main/java/org/apache/struts2/views/java/simple/HeadHandler.java
index 7eb7fa3..3af24d7 100644
--- a/plugins/javatemplates/src/main/java/org/apache/struts2/views/java/simple/HeadHandler.java
+++ b/plugins/javatemplates/src/main/java/org/apache/struts2/views/java/simple/HeadHandler.java
@@ -38,7 +38,7 @@ public class HeadHandler extends AbstractTagHandler implements TagGenerator {
             sb.append(base);
         }
         
-        sb.append("/struts/utils.js");
+        sb.append("/static/utils.js");
         attrs.put("src", sb.toString());
 
         super.start("script", attrs);
diff --git a/plugins/javatemplates/src/test/java/org/apache/struts2/views/java/simple/HeadTest.java b/plugins/javatemplates/src/test/java/org/apache/struts2/views/java/simple/HeadTest.java
index 92a205a..073da1f 100644
--- a/plugins/javatemplates/src/test/java/org/apache/struts2/views/java/simple/HeadTest.java
+++ b/plugins/javatemplates/src/test/java/org/apache/struts2/views/java/simple/HeadTest.java
@@ -31,7 +31,7 @@ public class HeadTest extends AbstractTest {
         map.putAll(tag.getParameters());
         theme.renderTag(getTagName(), context);
         String output = writer.getBuffer().toString();
-        String expected = s("<script type='text/javascript' base='/some/path' src='/some/path/struts/utils.js'></script>");
+        String expected = s("<script type='text/javascript' base='/some/path' src='/some/path/static/utils.js'></script>");
         assertEquals(expected, output);
     }