Summary: | ServletContext.getContext(String) cannot return context when using parallel deployments | ||
---|---|---|---|
Product: | Tomcat 7 | Reporter: | Charles <charles.phillips> |
Component: | Catalina | Assignee: | Tomcat Developers Mailing List <dev> |
Status: | RESOLVED FIXED | ||
Severity: | normal | CC: | charles.phillips |
Priority: | P2 | ||
Version: | 7.0.56 | ||
Target Milestone: | --- | ||
Hardware: | Macintosh | ||
OS: | All |
Description
Charles
2014-11-05 17:13:18 UTC
I'd like to point out that this gets complicated since Tomcat uses session identification to determine which version of the target web application will be used. Since the client likely didn't send their session identifier for the /other/ web application, ServletContext.getContext(String path) can't actually determine the correct ServletContext to return. Is it possible for you to avoid using ServletContext.getContext(String) in your application, and instead issue a blind redirect? Blind redirect isn't an option. We would rather just not use parallel deployments instead. This seams like a limiting factor of the servlet implementation when using parallel deployments. Is there no other way to get the context for cross context operations w/o knowing the specific version? I think the correct behaviour here would be for getContext("/foo_b") to return the latest version of foo_b, exactly as would happen if a user requested that URL. I like the idea of being able to specify a specific version if necessary although I'm not sure on the best way of doing this. I like /foo_b##ver but I wouldn't want that exposed to external clients. I suppose that's the best we can do, but if the client has a session with an older-than-latest-version of the /foo_b context, things might behave oddly. Also, when the request-processing switches to the other web application, there will either be no session available there (I've never bothered to read about the session implications of cross-context forwards) or the wrong session (the one from /foo_a). Charles, I think that even if Tomcat can do this for you, your application still might not be able to tolerate the situation. But I agree with both of you: doing *something* is better than doing nothing. +1 to returning the ServletContext that matches the latest-deployed version. This has been fixed in trunk, 8.0.x (for 8.0.16 onwards) and 7.0.x (for 7.0.58 onwards). An explicit version can be selected by appending ##version to the end of the context path. Otherwise, the latest available version will be returned. REOPENING. Reviewing r1642697 Using Mapper.map() for this purpose returns wrong result for missing contexts. The mapper maps prefix of an URL, and so for getContext("/foo/bar") it may return the context of "/foo" or the ROOT context. I added a test case in r1643536, but commented-out the check, as it currently fails. This needs either a special method in Mapper or in Host (such as getLatestVersion(contextName)), or a check that the path of returned context is the same as expected. A difference between Mapper and Host is that Mapper returns only those contexts that are available. Using Host may return a context that has been stopped or have not started yet. The same concern for the exact match branch of this method: does it need to return a non-started context, even if the name matches exactly? It needs to be a currently running context in all cases. I have a patch for this. I'll apply it shortly. Fixed. Fixed versions remain unchanged. |