Unfortunately, one of my key concepts in a big application I am
developing
stops working in the step from 5.1.0.1 -> 5.1.0.2. Our application has
all page
classes inside a subfolder, thus our internal tapestry pages all look
like
http://hostname/klubb/page
and there is one tapestry page 'dynamic' that handles all requests
without
the prefixing /klubb :
http://hostname/something/else.html
where it looks up '/something/else.html' from a database. The
configuration
for this is set up like this:
public void contributeHttpServletRequestHandler(
OrderedConfiguration<HttpServletRequestFilter>
configuration,
Global global,
ClubConfiguration clubconf)
{
configuration.add("CustomContenHandler", new
CustomContentHandler(global, clubconf),
"before:IgnoredPaths");
}
and the corresponding class:
public class CustomContentHandler implements HttpServletRequestFilter
{
private static String contentType;
private final Global _global;
private final ClubConfiguration _configuration;
private final Pattern clubAssetsMatcher;
private enum RequestType
{
START_PAGE, DYNAMIC_PAGE, TAPESTRY_ACTION
};
// this class is used to overwrite getServletPath for inserting our
own
// t5
// page at the beginning of the path
//
private class MyHTTPServletRequest extends HttpServletRequestWrapper
{
private final RequestType _type;
public MyHTTPServletRequest(HttpServletRequest
httpServletRequest, RequestType type)
{
super(httpServletRequest);
_type = type;
}
@Override
public String getServletPath()
{
String path = super.getServletPath();
if(_type == RequestType.START_PAGE)
{
if(path.equals("/"))
path = Constants.STARTPAGE;
return path;
}
if(_type == RequestType.DYNAMIC_PAGE)
return Constants.DYNAMIC_CLUB_URL + path.toLowerCase();
if(_type == RequestType.TAPESTRY_ACTION)
return Constants.TAPESTRY_ACTION_PREFIX + path;
return path;
}
}
public CustomContentHandler(final Global global, final
ClubConfiguration configuration)
{
_global = global;
_configuration = configuration;
String regExp = ".*\\.(";
Iterator<String> iterator = getSuffixes().keySet().iterator();
while(iterator.hasNext())
{
regExp = regExp + (getSuffixes().size() == 0 ? "" : "|") +
iterator.next();
}
clubAssetsMatcher = Pattern.compile(regExp + ")");
}
public boolean service(HttpServletRequest request,
HttpServletResponse response, HttpServletRequestHandler handler)
throws IOException
{
String path = request.getServletPath().toLowerCase();
if(path.equals("/") ||
path.startsWith(Constants.TAPESTRY_ACTION_PREFIX + "/"))
{
MyHTTPServletRequest newRequest = new
MyHTTPServletRequest(request, RequestType.START_PAGE);
return handler.service(newRequest, response);
}
if(path.startsWith(Constants.PRIVATE_ASSETS_PREFIX + "/"))
return handler.service(request, response);
if(path.startsWith(Constants.PRIVATE_DYNAMIC_ACTION_PREFIX) ||
path.startsWith(Constants.PRIVATE_STARTPAGE_ACTION_PREFIX))
{
MyHTTPServletRequest newRequest = new
MyHTTPServletRequest(request, RequestType.TAPESTRY_ACTION);
return handler.service(newRequest, response);
}
int club = _configuration.getClubNumberFromRequest(request);
Map<String,Object> keys = new HashMap<String,Object>();
keys.put(Dynamic.CLUB_PROPERTY, club);
keys.put(Dynamic.PATH_PROPERTY, path);
keys.put(Dynamic.PART_PROPERTY, "");
Expression condition = ExpressionFactory.matchAllDbExp(keys,
Expression.EQUAL_TO);
SelectQuery query = new SelectQuery(Dynamic.class, condition);
query.setName("#" + club + ":" + path + ":");
query.setCacheStrategy(QueryCacheStrategy.SHARED_CACHE);
List<Dynamic> rows =
_global.getReadOnlyObjectContext().performQuery(query);
Dynamic dynamic = rows.size() == 1 ? rows.get(0) : null;
// pass handling if this is a private asset (i.e. images that we
// use in our templates)
//
Matcher match = clubAssetsMatcher.matcher(path);
if(match.matches())
{
contentType = getSuffixes().get(match.group(1));
if(dynamic != null)
{
response.setContentType(contentType);
ServletOutputStream out = response.getOutputStream();
out.write(dynamic.getData());
out.close();
return true;
}
return false;
}
// test for customer pages but exclude our own pages
//
if(dynamic != null)
{
MyHTTPServletRequest newRequest = new
MyHTTPServletRequest(request, RequestType.DYNAMIC_PAGE);
return handler.service(newRequest, response);
}
response.sendError(404);
return true;
}
public Map<String,String> getSuffixes()
{
Map<String,String> suffixes = new HashMap<String,String>();
suffixes.put("ico", "image/x-icon");
suffixes.put("css", "text/css");
suffixes.put("js", "text/javascript");
suffixes.put("gif", "image/gif");
suffixes.put("jpg", "image/jpeg");
suffixes.put("jpeg", "image/jpeg");
suffixes.put("png", "image/png");
suffixes.put("tif", "mage/tif");
suffixes.put("tiff", "mage/tiff");
suffixes.put("pdf", "application/pdf");
suffixes.put("xml", "text/xml");
suffixes.put("doc", "application/msword");
suffixes.put("docx", "application/msword");
suffixes.put("xsl", "application/x-excel");
suffixes.put("txt", "text/plain");
suffixes.put("gzip", "application/x-gzip");
suffixes.put("zip", "application/zip");
suffixes.put("tar", "application/x-tar");
suffixes.put("cab", "application/octet-stream");
suffixes.put("dmg", "application/octet-stream");
suffixes.put("tgz", "application/x-tar");
suffixes.put("rar", "application/x-rar-compressed");
suffixes.put("exe", "application/octet-stream");
suffixes.put("mp3", "application/octet-stream");
suffixes.put("wav", "application/octet-stream");
suffixes.put("aac", "application/octet-stream");
suffixes.put("ra", "application/octet-stream");
suffixes.put("wma", "application/octet-stream");
suffixes.put("mov", "application/octet-stream");
suffixes.put("mp4", "application/octet-stream");
suffixes.put("wmv", "application/octet-stream");
suffixes.put("avi", "application/octet-stream");
return suffixes;
}
}
The stack trace is here:
java.lang.RuntimeException: Exception constructing service
'HttpServletRequestHandler': Construction of service
'HttpServletRequestHandler' has failed due to recursion: the service
depends on itself in some way. Please check
org
.apache
.tapestry5
.services.TapestryModule.buildHttpServletRequestHandler(Logger, List,
RequestHandler, String, SessionPersistedObjectAnalyzer) (at
TapestryModule.java:1222) for references to another service that is
itself dependent on service 'HttpServletRequestHandler'.
at
org
.apache
.tapestry5
.ioc
.internal
.services
.JustInTimeObjectCreator
.obtainObjectFromCreator(JustInTimeObjectCreator.java:78)
at
org
.apache
.tapestry5
.ioc
.internal
.services
.JustInTimeObjectCreator.createObject(JustInTimeObjectCreator.java:57)
at
$
HttpServletRequestHandler_1206bab64a5
.delegate($HttpServletRequestHandler_1206bab64a5.java)
at
$
HttpServletRequestHandler_1206bab64a5
.service($HttpServletRequestHandler_1206bab64a5.java)
at org.apache.tapestry5.TapestryFilter.doFilter(TapestryFilter.java:
127)
at org.mortbay.jetty.servlet.ServletHandler
$CachedChain.doFilter(ServletHandler.java:1084)
at
org
.apache
.cayenne
.conf
.WebApplicationContextFilter.doFilter(WebApplicationContextFilter.java:
90)
at org.mortbay.jetty.servlet.ServletHandler
$CachedChain.doFilter(ServletHandler.java:1084)
at
org.mortbay.jetty.servlet.ServletHandler.handle(ServletHandler.java:360)
at
org.mortbay.jetty.security.SecurityHandler.handle(SecurityHandler.java:
216)
at
org.mortbay.jetty.servlet.SessionHandler.handle(SessionHandler.java:181)
at
org.mortbay.jetty.handler.ContextHandler.handle(ContextHandler.java:722)
at org.mortbay.jetty.webapp.WebAppContext.handle(WebAppContext.java:
404)
at
org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:139)
at org.mortbay.jetty.Server.handle(Server.java:324)
at org.mortbay.jetty.HttpConnection.handleRequest(HttpConnection.java:
505)
at org.mortbay.jetty.HttpConnection
$RequestHandler.headerComplete(HttpConnection.java:828)
at org.mortbay.jetty.HttpParser.parseNext(HttpParser.java:514)
at org.mortbay.jetty.HttpParser.parseAvailable(HttpParser.java:211)
at org.mortbay.jetty.HttpConnection.handle(HttpConnection.java:380)
at
org
.mortbay.io.nio.SelectChannelEndPoint.run(SelectChannelEndPoint.java:
395)
at org.mortbay.thread.BoundedThreadPool
$PoolThread.run(BoundedThreadPool.java:450)
Caused by: org.apache.tapestry5.ioc.internal.OperationException:
Construction of service 'HttpServletRequestHandler' has failed due to
recursion: the service depends on itself in some way. Please check
org
.apache
.tapestry5
.services.TapestryModule.buildHttpServletRequestHandler(Logger, List,
RequestHandler, String, SessionPersistedObjectAnalyzer) (at
TapestryModule.java:1222) for references to another service that is
itself dependent on service 'HttpServletRequestHandler'.
at
org
.apache
.tapestry5
.ioc.internal.OperationTrackerImpl.invoke(OperationTrackerImpl.java:90)
at
org
.apache
.tapestry5
.ioc
.internal
.PerThreadOperationTracker.invoke(PerThreadOperationTracker.java:68)
at
org
.apache.tapestry5.ioc.internal.RegistryImpl.invoke(RegistryImpl.java:
941)
at
org
.apache
.tapestry5
.ioc
.internal
.OperationTrackingObjectCreator
.createObject(OperationTrackingObjectCreator.java:49)
at
org
.apache
.tapestry5
.ioc
.internal
.services
.JustInTimeObjectCreator
.obtainObjectFromCreator(JustInTimeObjectCreator.java:68)
... 21 more
Caused by: java.lang.IllegalStateException: Construction of service
'HttpServletRequestHandler' has failed due to recursion: the service
depends on itself in some way. Please check
org
.apache
.tapestry5
.services.TapestryModule.buildHttpServletRequestHandler(Logger, List,
RequestHandler, String, SessionPersistedObjectAnalyzer) (at
TapestryModule.java:1222) for references to another service that is
itself dependent on service 'HttpServletRequestHandler'.
at
org
.apache
.tapestry5
.ioc
.internal
.RecursiveServiceCreationCheckWrapper
.createObject(RecursiveServiceCreationCheckWrapper.java:52)
at org.apache.tapestry5.ioc.internal.OperationTrackingObjectCreator
$1.invoke(OperationTrackingObjectCreator.java:45)
at
org
.apache
.tapestry5
.ioc.internal.OperationTrackerImpl.invoke(OperationTrackerImpl.java:68)
... 25 more
On 3 apr 2009, at 01.41, Howard Lewis Ship wrote:
The latest alpha release of Tapestry 5.1, Tapestry 5.1.0.2, is now
available for download and via Maven.
Please download it and give it a try; we're especially interested in
any problems related to the upgrade from 5.0.18 to 5.1.0.2.
Big features added in 5.1.0.2 include automatic combining of
JavaScript files, a new client-side JavaScript console based on
Blackbird, and the ability to have a single Ajax response update
multiple client-side Zones.
We are now stabilizing Tapestry 5.1 for a beta release and, if all
goes according to plan, a short period until a stable 5.1 release.
--
Howard M. Lewis Ship
Creator Apache Tapestry and Apache HiveMind
---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscr...@tapestry.apache.org
For additional commands, e-mail: users-h...@tapestry.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscr...@tapestry.apache.org
For additional commands, e-mail: users-h...@tapestry.apache.org