You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tapestry.apache.org by Doug Dew <dd...@insightbb.com> on 2003/07/03 16:16:25 UTC
Tapestry malfunctions when Tomcat is fronted by Apache httpd
All,
I'm attempting to use Tapestry for a web app that will be hosted at
javaservlethosting.com. At javaservlethosting.com all Tomcat instances are
fronted by Apache httpd instances, and requests are passed through the httpd
instances to the Tomcat instances.
I'm attempting to make javaservlethosting.com's default httpd pass-through
configuration for "/servlet/*" work with Tapestry. Specifically, I've mapped
the Tapestry ApplicationServlet in web.xml as follows:
<servlet>
<servlet-name>ApplicationServlet</servlet-name>
<servlet-class>org.apache.tapestry.ApplicationServlet</servlet-class>
<load-on-startup>0</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>ApplicationServlet</servlet-name>
<url-pattern>/servlet/app</url-pattern>
</servlet-mapping>
With such a servlet mapping, the following request causes the Tapestry
ApplicationServlet to be called:
http://www.foo.com/servlet/app
However, upon being called, the ApplicationServlet fails to correctly
service the request due to being unable to find the /Home.html file.
Everything had been working okay on my dev machine where there is no httpd
pass-through stuff and where my Tapestry ApplicationServlet is mapped to the
more conventional "/app". So, I spent some time in my debugger to track down
the problem.
According to what I've seen in my debugger, the problem seems to be in
Tapestry.getApplicationRootLocation:
public static IResourceLocation getApplicationRootLocation(IRequestCycle
cycle)
{
RequestContext context = cycle.getRequestContext();
ServletContext servletContext =
context.getServlet().getServletContext();
String servletPath = context.getRequest().getServletPath();
// Could strip off the servlet name (i.e., "app" in "/app") but
// there's no need.
return new ContextResourceLocation(servletContext, servletPath);
}
As you can tell by the code, there's no provision for the possibility that
somebody might have invoke the Tapestry ApplicationServlet with a request
like http://www.foo.com/servlet/app. As a result, the "/servlet/app" value
of the servletPath variable is used without adjustment to create the
ContextResourceLocation. This causes things like template searches to fail
because the template searches are told that the web app root is "/servlet"
and so searches occur for Home.html at /servlet/Home.html instead of at
/Home.html.
I've coded a workaround to this problem by using your pluggable template
source delegate scheme to provide my own template source delegate that
doesn't call Tapestry.getApplicationRootLocation to figure out the web app
root. This enables me to find my templates, but of course doesn't fix the
problem very nicely and also doesn't fix the related problem of finding
page/component specifications.
Please code and make available a fix to this problem so Tapestry will be
more hosting environment friendly.
By the way, in my opinion, it would be *much* easier to create template
source delegates if DefaultTemplateSource were more re-usable as an
inheritance base. Right now, most of DefaultTemplateSource's methods are
private and there aren't any getters/setters for the private instance
members, so deriving from DefaultTemplateSource is a pain.
Thank you in advance for your assistance. And thank you for the cool code.
Despite the occasional bug here and there, Tapestry is way better than the
alternatives.
Doug