tomcat-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Brett McLaughlin" <>
Subject Re: ContextPath, ServletPath and backwards compatibility
Date Thu, 18 Nov 1999 02:26:38 GMT
> Hey all,
> I seem to recall that issues surrounding this topic have recently been
> discussed, but I am unaware of any archives for the Jakarta lists, nor
> did I save any of the discussions.  Apologies if this is redundant.
> Recently, I got Turbine to run on Tomcat.  The main problem (so far)
> resulted from the use in Turbine of the
> HttpServletRequest.getServletPath().  I lazily placed Turbine inside
> the /examples context.  Turbine uses the getServletPath() method to
> figure out how it was called, and builds its response from that
> information.

This is fixed in Turbine, with the hack in your mail.  Yes it's ugly, but
major changes in a spec often result in ugly hacks for a while, until
everybody gets caught up.

> As a result, under Tomcat, Turbine kept dropping the "/examples" part
> of the URL (since getServletPath() doesn't return the context part in
> Tomcat).  Naturally, this caused Turbine to break.
> However, according to the spec, Tomcat seems to be behaving correctly.

Yeah, it is actually doing exactly what the spec says it should.

> The "obvious fix" is heinous, and goes something like this:
>     // Allow Turbine to work with both 2.2 and 2.0 Servlet API
>     Class clazz = req.getClass();
>     try {
> java.lang.reflect.Method meth =
>                     clazz.getDeclaredMethod("getContextPath", null);
> data.scriptName = (String)meth.invoke(req, null);
>     } catch (Exception ex) {}
>     data.scriptName += req.getServletPath();
> This is very unpleasant and inefficient.

This is not as inefficient as you think.

1) Because the servlet engine will already have the jsdk classes loaded,
there is no hit for getting a handle to the class.  A class is only loaded
once; so you pay minimally here.
2) This (in Turbine) is done once, at the initial servlet call, then cached.
The whole reason for caching is, quite frankly, to hide the code of heinous
and time-consuming behaviour, so this isn't too bad either.
3) It still beats the pants off EJB :-)  EJB is great, but there's a lot
more than just one reflection call going on in a container!

> I suppose I would have argued that the getServletPath() method should
> have been backwards compatible, behaving like it did in the 2.0 JSDK,
> and returning the "full" servlet path, context included.  One could
> then trivially obtain the non-context part by getting a substring.  As
> it is, this new behaviour seems likely to break many applications, and
> force ugly, inefficient hacks to make them compatible with the
> different API versions.

I don't know - with the introduction of context, it seems Sun is moving more
towards a uniform way of handling namespaces - EJB has been using enContexts
for a while now, and this is a good step in soldifying things into a
cohesive unit.  There is also a substantial difference between a servlet
path and the servlet context, as well as what the class loader/servlet
engine needs to discover about a servlet at load time.  I think 2.2 spec is
a mjor change; as great as that is, major changes cause problems for a
while.  That's sort of just the way it goes; unfortunate, but the whole J2EE
bundle changes the playing field quite a bit... we're working on EJBoss and
I work with some guys at Persistence, and there are major changes there
because of spec changes too... that's progress for ya! :-)

> I suppose, however, that it may be possible to change Turbine in such
> a way that the above hack is not necessary.  I currently don't know
> how to do that, though.

Well, I will work on a better solution (or at least think about if there is
one) later this week; I'm using Tomcat at work, and seeing as I'm one of the
guilty parties who came up with Turbine :-) I suppose I should fix it

> Comments?

We can change Turbine much easier than changing the spec.  I know that this
is a bigger issue than that, but I don't think servlets are old enough to
have lots of "legacy" code laying around that can't suffer a few tweaks for
the sake of a better API.  Just my thoughts.


View raw message