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

Reply via email to