Adding Tiles to a Struts 1.3 Project with a Custom Request Processor

In Struts, if you wanted to do funny shenanigans (e.g. override the Roles checking for authorization, or override the ActionForm population to parse a JSON object rather than standard parameters) with the Struts Controller, up until Struts 1.2, you had to extend the Request Processor and configure the Struts ActionServlet to use it instead. This would get rather complicated when you tried to layer multiple custom controllers together, such as with the Validator and the Tiles plugins.

Struts 1.3 changed this behavior. Rather than all of the heavy lifting being offloaded onto the RequestProcessor object by the ActionServlet, instead there’s a chain of commands executed by a class called “ComposableRequestProcessor, and it’s configured by chain-config.xml; which is in the struts-core JAR file. If you want to extend the controller to do out-of-the-ordinary stuff, you’re supposed to copy this file to somewhere else (like /WEB-inF/custom-chain-config.xml) edit it, and configure the ActionServlet to look at it instead like this

<servlet>
 <servlet-name>action</servlet-name>
 <servlet-class>org.apache.struts.action.ActionServlet</servlet-class>
 <init-param>
  <param-name>config</param-name>
  <param-value>/WEB-INF/struts-config.xml</param-value>
 </init-param>
 <init-param>
  <param-name>chainConfig</param-name>
  <param-value>/WEB-INF/custom-chain-config.xml</param-value>
 </init-param>
</servlet>

The trouble however, is that the Struts Tiles plugin that shipped with 1.3 didn’t change from 1.2. It was written to automatically replace the default RequestProcessor and its chain of command. I’m pretty sure this was supposed to be a convenience, so that to use the Tiles plugin, all you had to do was flip a switch, and it would figure out its own hooks into Struts… because this is how the Struts Tiles plugin works; it essentially overrides and customizes the RequestProcessor so forwards goto it, rather than to some JSP file or somerthing somewhere. You can see how it’s doing this overriding by looking at the method TilesPlugin.initRequestProcessorClass; which is actually a little interesting, because it’s not mucking with any XML. But that’s all you really have to do, usually.

However, and this is why I’m posting this; if you have a custom chain-config.xml already in place that was based on the chain-config.xml in the struts-core JAR, then your ActionForwards going to Tiles layouts aren’t going to lookup correctly. For example, when Struts tries to goto the ActionForward “page.index”, we get the following exception because normally ActionForwards would goto a page like “/index.jsp”.

WARNING: Unhandled exception
java.lang.IllegalArgumentException: Path page.index does not start with a "/" character
	at org.apache.catalina.core.ApplicationContext.getRequestDispatcher(ApplicationContext.java:374)
	at org.apache.catalina.core.ApplicationContextFacade.getRequestDispatcher(ApplicationContextFacade.java:196)
	at org.apache.struts.chain.commands.servlet.PerformForward.handleAsForward(PerformForward.java:107)
	at org.apache.struts.chain.commands.servlet.PerformForward.perform(PerformForward.java:96)
	at org.apache.struts.chain.commands.AbstractPerformForward.execute(AbstractPerformForward.java:54)
	at org.apache.struts.chain.commands.ActionCommandBase.execute(ActionCommandBase.java:51)
	at org.apache.commons.chain.impl.ChainBase.execute(ChainBase.java:191)
	at org.apache.commons.chain.generic.LookupCommand.execute(LookupCommand.java:305)
	at org.apache.commons.chain.impl.ChainBase.execute(ChainBase.java:191)
	at org.apache.struts.chain.ComposableRequestProcessor.process(ComposableRequestProcessor.java:283)
	at org.apache.struts.action.ActionServlet.process(ActionServlet.java:1913)
	at org.apache.struts.action.ActionServlet.doGet(ActionServlet.java:449)
        ...

As far as cryptic errors go, this one is pretty far up there, and unless you actually know how Tiles works, it’s going to be a huge pain to debug. The remedy is actually to base your chain-config.xml file off of Tiles’ own chain-config.xml. And in it you can see how at the end it calls TilesPreProcessor right before it performs the forward.

The Tiles documentation indeed says you need to do this — but hardly anyone ever does, because everything will work unless you customize the request processor; and hardly any books or sites out there will tell you to do it.

8 Comments

  • Madan Neelapu
    Posted June 23, 2014 at 10:25 am | Permalink

    hi philip,

    your article saved my day. thanks a lot 🙂

    • philihp
      Posted July 8, 2014 at 6:08 am | Permalink

      Glad to hear it!

      • naseer Mohammed abdul
        Posted November 8, 2017 at 5:47 pm | Permalink

        Currently we are trying to migrate from Struts-tiles to Apache tiles in Struts 1.3 project. I Need to know how to plug-in the apache tiles in struts-config.xml so it can resolve the view from tiles definitions. can you please suggest me how to do this. Immediate response is appreciated.

        • Philihp
          Posted November 8, 2017 at 7:03 pm | Permalink

          Hi Naseer,

          Do you have a repo that I can take a look at?

          Does this documentation help? https://tiles.apache.org/framework/migration/index.html

          Additionally, maybe take a look at this project, which appears to have used apache-tiles and struts 1.3: https://github.com/quikkian-ua-devops/will-financials

          • naseer Mohammed abdul
            Posted November 8, 2017 at 9:16 pm | Permalink

            thanks for the reply,

            Its a simple struts 1.x project with struts-tiles . the action forwardMapping is going to tiles definition. its working if i use struts-tiles plug-in. but my take is to replace struts-tiles with apache tiles and rest of the struts framework as it is. so the struts-tiles plugin is pointing to

            I want to do someway to integrate struts with apache tiles. let me know if this make any sense to you.

  • naseer Mohammed abdul
    Posted November 8, 2017 at 9:17 pm | Permalink

    thanks for the reply,

    Its a simple struts 1.x project with struts-tiles . the action forwardMapping is going to tiles definition. its working if i use struts-tiles plug-in. but my take is to replace struts-tiles with apache tiles and rest of the struts framework as it is. so the struts-tiles plugin is pointing to

    I want to do someway to integrate struts with apache tiles. let me know if this make any sense to you.

    • naseer Mohammed abdul
      Posted November 8, 2017 at 9:18 pm | Permalink

      className=”org.apache.struts.tiles.TilesPlugin”
      set-property property=”definitions-config”
      value=”/WEB-INF/tiles-defs.xml”

      • Philihp
        Posted November 9, 2017 at 7:18 pm | Permalink

        From this old documentation here: https://tiles.apache.org/2.2/framework/tutorial/integration/frameworks.html

        It looks as though apache-tiles 2 support for struts 1.x was in development for 1.4 which was never released (1.3 was the last version, almost 10 years ago). If you want to figure out how to pull from Subversion, you might be able to dig it up, but that might not be worth the effort.

        If you want to upgrade from struts-tiles to apache-tiles 2 (not even to 3), it might be a better idea to upgrade to Struts 2 first.

Post a Comment

Your email is kept private. Required fields are marked *