You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@geronimo.apache.org by Paul McMahan <pa...@gmail.com> on 2007/04/17 17:02:22 UTC

need help on Tomcat and EJB web services

Jarek and I have been struggling with an issue we encountered in  
Geronimo's TomcatEJBWebService that has to do with how EJB web  
services become URL addressable after they are deployed.   You can  
see the full discussion here:
     https://issues.apache.org/jira/browse/GERONIMO-2841

In a nutshell, the basic problem is that when an HTTP client requests  
http://hostname/context Tomcat will automatically redirect the  
request to http://hostname/context/  (note the trailing slash).  This  
behavior is mandated by section 9.10 of the servlet 2.4 specification  
which says:
     "A request URI of /foo will be redirected to a URI of /foo/"

The reason this behavior causes a problem for our web services  
implementation is because when Geronimo's EJBWebServiceGBean deploys  
a web service it uses a context without the trailing slash, e.g. "/ 
JAXWSBeanService/JAXWSBean".  Then a web service client sends a POST  
request to that location, http://hostname/JAXWSBeanService/JAXWSBean,  
Since that URL corresponds to a context Tomcat responds with a  
redirect URL that appends the trailing slash.  Jarek has found that  
this redirect causes a problem for web service clients because they  
will respond to it with a GET instead of a POST, thus losing the  
original method and structure of the request by the time it reaches  
the web services container.

In case you're wondering, Jetty also exhibits this redirect behavior  
by default and Geronimo's JettyEJBWebService avoids it by overriding  
ContextHandler.handle().  But Tomcat implements this redirect  
behavior at the connector level and and I have not found any  
reasonable way to override it (maybe I am overlooking something).  It  
used to be configurable but that support was explicitly removed:
     http://svn.apache.org/viewvc?view=rev&revision=298787

At this point we have identified the following options.  Any feedback  
you can provide would be very helpful.

1.)  Figure out some clever way to "outsmart" Tomcat and avoid the  
redirect behavior.  I haven't found any way to do this but maybe  
someone else has an idea.  Maybe this is not desirable since it  
arguably violates the servlet spec.
2.)  Ask Tomcat to reimplement the configuration option they removed  
in rev 298787 that would allow us to avoid the redirect behavior.   
Again, maybe not desirable since it arguably violates the servlet spec.
3.)  Redesign TomcatEJBWebService to deploy web services as servlets  
instead of contexts.  This would be a significant design change and  
would also be inconsistent with our current implementation in Jetty.
4.)  Expect web service clients to follow redirects more  
intelligently, i.e. respond to a redirect from a POST request with  
another POST instead of a GET.  IIUC this may cause problems with  
TCK? (Jarek can elaborate).
5.)  other ideas?


Best wishes,
Paul

Re: need help on Tomcat and EJB web services

Posted by Jeff Genender <jg...@apache.org>.
Yup...thats a problem.

Jeff

Paul McMahan wrote:
> On Apr 17, 2007, at 1:28 PM, Jeff Genender wrote:
> 
>> Can you step through it and see where its occurring?  We did a special
>>
>> trick with the DefaultSubject vlave IIRC that had to inject it before
>>
>> everything else.  I recall we did something funky.  If you can find
>>
>> where it occurs, I may be able to help you get around this ;-)
>> Hopefully ;-)
>>
>>
>> Jeff
>>
> 
> Bummer.   Stepping through the CoyoteAdapter source I found that the
> redirect occurs just before the first valve is called:
> 
> // Parse and set Catalina and configuration specific
> // request parameters
> if (postParseRequest(req, request, res, response)) {
>     // Calling the container
>     connector.getContainer().getPipeline().getFirst().invoke(request,
> response);
> 
> 
> The redirect occurs during postParseRequest()
> 
> Best wishes,
> Paul

Re: need help on Tomcat and EJB web services

Posted by Paul McMahan <pa...@gmail.com>.
On Apr 17, 2007, at 1:28 PM, Jeff Genender wrote:

> Can you step through it and see where its occurring?  We did a special
> trick with the DefaultSubject vlave IIRC that had to inject it before
> everything else.  I recall we did something funky.  If you can find
> where it occurs, I may be able to help you get around this ;-)  
> Hopefully ;-)
>
> Jeff

Bummer.   Stepping through the CoyoteAdapter source I found that the  
redirect occurs just before the first valve is called:

// Parse and set Catalina and configuration specific
// request parameters
if (postParseRequest(req, request, res, response)) {
     // Calling the container
     connector.getContainer().getPipeline().getFirst().invoke 
(request, response);


The redirect occurs during postParseRequest()

Best wishes,
Paul

Re: need help on Tomcat and EJB web services

Posted by Jeff Genender <jg...@apache.org>.
Can you step through it and see where its occurring?  We did a special
trick with the DefaultSubject vlave IIRC that had to inject it before
everything else.  I recall we did something funky.  If you can find
where it occurs, I may be able to help you get around this ;-) Hopefully ;-)

Jeff

Paul McMahan wrote:
> On Apr 17, 2007, at 11:55 AM, Jeff Genender wrote:
> 
>> Why not use a low level Valve to trap the HTTP call before a redirect
>>
>> can occur?
>>
>>
>> Jeff
>>
> 
> Maybe there is some way to do that.  But it looks to me like the
> redirect occurs before the first valve is called.   At least that's what
> I observed when I set the EJBWebServiceValve as the basic valve instead
> of just adding it to the context, like so:
> 
> ---
> src/main/java/org/apache/geronimo/tomcat/TomcatEJBWebServiceContext.java 
>   (revision 529223)
> +++
> src/main/java/org/apache/geronimo/tomcat/TomcatEJBWebServiceContext.java 
>   (working copy)
> @@ -127,7 +127,7 @@
>              isSecureTransportGuarantee = false;
>          }
>          this.classLoader = classLoader;
> -        this.addValve(new EJBWebServiceValve());
> +        this.setBasic(new EJBWebServiceValve());
>      }
> 
> Best wishes,
> Paul

Re: need help on Tomcat and EJB web services

Posted by Paul McMahan <pa...@gmail.com>.
On Apr 17, 2007, at 11:55 AM, Jeff Genender wrote:

> Why not use a low level Valve to trap the HTTP call before a redirect
> can occur?
>
> Jeff

Maybe there is some way to do that.  But it looks to me like the  
redirect occurs before the first valve is called.   At least that's  
what I observed when I set the EJBWebServiceValve as the basic valve  
instead of just adding it to the context, like so:

--- src/main/java/org/apache/geronimo/tomcat/ 
TomcatEJBWebServiceContext.java    (revision 529223)
+++ src/main/java/org/apache/geronimo/tomcat/ 
TomcatEJBWebServiceContext.java    (working copy)
@@ -127,7 +127,7 @@
              isSecureTransportGuarantee = false;
          }
          this.classLoader = classLoader;
-        this.addValve(new EJBWebServiceValve());
+        this.setBasic(new EJBWebServiceValve());
      }

Best wishes,
Paul

Re: need help on Tomcat and EJB web services

Posted by Jeff Genender <jg...@apache.org>.
Why not use a low level Valve to trap the HTTP call before a redirect
can occur?

Jeff

David Jencks wrote:
> 
> On Apr 17, 2007, at 8:02 AM, Paul McMahan wrote:
> 
>> Jarek and I have been struggling with an issue we encountered in
>> Geronimo's TomcatEJBWebService that has to do with how EJB web
>> services become URL addressable after they are deployed.   You can see
>> the full discussion here:
>>     https://issues.apache.org/jira/browse/GERONIMO-2841
>>
>> In a nutshell, the basic problem is that when an HTTP client requests
>> http://hostname/context Tomcat will automatically redirect the request
>> to http://hostname/context/  (note the trailing slash).  This behavior
>> is mandated by section 9.10 of the servlet 2.4 specification which says:
>>     "A request URI of /foo will be redirected to a URI of /foo/"
>>
>> The reason this behavior causes a problem for our web services
>> implementation is because when Geronimo's EJBWebServiceGBean deploys a
>> web service it uses a context without the trailing slash, e.g.
>> "/JAXWSBeanService/JAXWSBean".  Then a web service client sends a POST
>> request to that location, http://hostname/JAXWSBeanService/JAXWSBean,
>> Since that URL corresponds to a context Tomcat responds with a
>> redirect URL that appends the trailing slash.  Jarek has found that
>> this redirect causes a problem for web service clients because they
>> will respond to it with a GET instead of a POST, thus losing the
>> original method and structure of the request by the time it reaches
>> the web services container.
>>
>> In case you're wondering, Jetty also exhibits this redirect behavior
>> by default and Geronimo's JettyEJBWebService avoids it by overriding
>> ContextHandler.handle().  But Tomcat implements this redirect behavior
>> at the connector level and and I have not found any reasonable way to
>> override it (maybe I am overlooking something).  It used to be
>> configurable but that support was explicitly removed:
>>     http://svn.apache.org/viewvc?view=rev&revision=298787
>>
>> At this point we have identified the following options.  Any feedback
>> you can provide would be very helpful.
>>
>> 1.)  Figure out some clever way to "outsmart" Tomcat and avoid the
>> redirect behavior.  I haven't found any way to do this but maybe
>> someone else has an idea.  Maybe this is not desirable since it
>> arguably violates the servlet spec.
>> 2.)  Ask Tomcat to reimplement the configuration option they removed
>> in rev 298787 that would allow us to avoid the redirect behavior. 
>> Again, maybe not desirable since it arguably violates the servlet spec.
>> 3.)  Redesign TomcatEJBWebService to deploy web services as servlets
>> instead of contexts.  This would be a significant design change and
>> would also be inconsistent with our current implementation in Jetty.
> 
> My guess is this is the best bet, but I couldn't figure out what context
> root and servlet-mapping would apply to  an ejb web service.  Does
> tomcat let you deploy a lot of apps at the same context-root?  If so,
> perhaps we can deploy each ejb-ws at "/"
> 
> I'm not very worried about the tomcat implementation being different
> from the jetty implementation.  I'm more worried about this being a lot
> of work.  We might need to implement the tomcat object that runs
> Digester to construct the servlet wrapper for us.
> 
> thanks
> david jencks
> 
>> 4.)  Expect web service clients to follow redirects more
>> intelligently, i.e. respond to a redirect from a POST request with
>> another POST instead of a GET.  IIUC this may cause problems with TCK?
>> (Jarek can elaborate).
>> 5.)  other ideas?
>>
>>
>> Best wishes,
>> Paul

Re: need help on Tomcat and EJB web services

Posted by David Jencks <da...@yahoo.com>.
On Apr 17, 2007, at 8:02 AM, Paul McMahan wrote:

> Jarek and I have been struggling with an issue we encountered in  
> Geronimo's TomcatEJBWebService that has to do with how EJB web  
> services become URL addressable after they are deployed.   You can  
> see the full discussion here:
>     https://issues.apache.org/jira/browse/GERONIMO-2841
>
> In a nutshell, the basic problem is that when an HTTP client  
> requests http://hostname/context Tomcat will automatically redirect  
> the request to http://hostname/context/  (note the trailing  
> slash).  This behavior is mandated by section 9.10 of the servlet  
> 2.4 specification which says:
>     "A request URI of /foo will be redirected to a URI of /foo/"
>
> The reason this behavior causes a problem for our web services  
> implementation is because when Geronimo's EJBWebServiceGBean  
> deploys a web service it uses a context without the trailing slash,  
> e.g. "/JAXWSBeanService/JAXWSBean".  Then a web service client  
> sends a POST request to that location, http://hostname/ 
> JAXWSBeanService/JAXWSBean, Since that URL corresponds to a context  
> Tomcat responds with a redirect URL that appends the trailing  
> slash.  Jarek has found that this redirect causes a problem for web  
> service clients because they will respond to it with a GET instead  
> of a POST, thus losing the original method and structure of the  
> request by the time it reaches the web services container.
>
> In case you're wondering, Jetty also exhibits this redirect  
> behavior by default and Geronimo's JettyEJBWebService avoids it by  
> overriding ContextHandler.handle().  But Tomcat implements this  
> redirect behavior at the connector level and and I have not found  
> any reasonable way to override it (maybe I am overlooking  
> something).  It used to be configurable but that support was  
> explicitly removed:
>     http://svn.apache.org/viewvc?view=rev&revision=298787
>
> At this point we have identified the following options.  Any  
> feedback you can provide would be very helpful.
>
> 1.)  Figure out some clever way to "outsmart" Tomcat and avoid the  
> redirect behavior.  I haven't found any way to do this but maybe  
> someone else has an idea.  Maybe this is not desirable since it  
> arguably violates the servlet spec.
> 2.)  Ask Tomcat to reimplement the configuration option they  
> removed in rev 298787 that would allow us to avoid the redirect  
> behavior.  Again, maybe not desirable since it arguably violates  
> the servlet spec.
> 3.)  Redesign TomcatEJBWebService to deploy web services as  
> servlets instead of contexts.  This would be a significant design  
> change and would also be inconsistent with our current  
> implementation in Jetty.

My guess is this is the best bet, but I couldn't figure out what  
context root and servlet-mapping would apply to  an ejb web service.   
Does tomcat let you deploy a lot of apps at the same context-root?   
If so, perhaps we can deploy each ejb-ws at "/"

I'm not very worried about the tomcat implementation being different  
from the jetty implementation.  I'm more worried about this being a  
lot of work.  We might need to implement the tomcat object that runs  
Digester to construct the servlet wrapper for us.

thanks
david jencks

> 4.)  Expect web service clients to follow redirects more  
> intelligently, i.e. respond to a redirect from a POST request with  
> another POST instead of a GET.  IIUC this may cause problems with  
> TCK? (Jarek can elaborate).
> 5.)  other ideas?
>
>
> Best wishes,
> Paul