Details
-
Type:
Bug
-
Status:
Resolved
-
Priority:
Minor
-
Resolution: Fixed
-
Affects Version/s: 6.1.9
-
Component/s: Continuations
-
Labels:None
-
Environment:GWT1.5M2+ trying to use OpenRemoteServiceServlet
-
Number of attachments :2
Description
I understand GWT1.5 isn't released yet, but many developers are trying it out because it's very close to release. Understand it's probably to bleeding edge - you should proably wait until at least a release candidate, but I just wanted to give you a heads up.
The RemoteServiceServlet will be stable now because it's such a core part of GWT. They've changed the call to RPCServletUtils.readContentAsUtf8(request); and I naively changed that, but now I get the com.google.gwt.user.client.rpc.SerializationException: Type 'org.mortbay.jetty.RetryRequest' was not assignable to 'com.google.gwt.user.client.rpc.IsSerializable' and did not have a custom field serializer. Haven't really got familiar enough with the code yet to understand what's going on.
I am really looking forward to seeing this all work guys - using continuations in the way you have is a fantastic concept![]()
-
- FixedRemoteServiceServlet.java
- 21/Jun/08 5:33 AM
- 14 kB
- Raphaël POCHET
-
- FixedRPC.java
- 21/Jun/08 5:33 AM
- 33 kB
- Raphaël POCHET
Activity
Hi Jan,
Sorry I've not replied here, but I've been 'offline' for a month.
Could you clarify last comment? Do do you mean GWT1.5 is available or the fix is in, ie. jetty with GWT1.5 fix is available for download?
Cheers,
Tony
PS GWT Servlet source can be found at http://google-web-toolkit.googlecode.com/svn/tags/1.5.0/user/src/com/google/gwt/user/server/rpc/RemoteServiceServlet.java
Hello there
Have you any news on this issue because i'm experiencing troubles too with jetty 6.1.8 and GWT 1.5 RC1
Jetty throws a RetryRequest on continuation.suspend
wich is catched by gwt in RPC.
I changed the code of the RemoteServiceServlet in invokeAndEncodeResponse(Object, Method, Object[], SerializationPolicy) to propagate the RetryRequest to webcontainer (jetty).
So the code is like this now :
public static String invokeAndEncodeResponse(Object target, Method serviceMethod, Object[] args, SerializationPolicy serializationPolicy) throws SerializationException {
if (serviceMethod == null)
if (serializationPolicy == null)
{ throw new NullPointerException("serializationPolicy"); } String responsePayload = null;
try
catch (IllegalAccessException e)
{ SecurityException securityException = new SecurityException( formatIllegalAccessErrorMessage(target, serviceMethod)); securityException.initCause(e); throw securityException; }catch (IllegalArgumentException e)
{ SecurityException securityException = new SecurityException( formatIllegalArgumentErrorMessage(target, serviceMethod, args)); securityException.initCause(e); throw securityException; } catch (InvocationTargetException e) {
// Try to encode the caught exception
//
Throwable cause = e.getCause();
if (e.getTargetException() instanceof RetryRequest)
else
{ responsePayload = encodeResponseForFailure(serviceMethod, cause, serializationPolicy); }}
return responsePayload;
}
But if i write the following code in a GWT Servlet (wich extends RemoteServiceServlet which uses RPC) :
if(!client.hasEvents()) {
synchronized(this)
}
i still get the following exception :
2008-06-18 22:53:20.942:/GWT_Dual_Server:WARN: Exception while dispatching incoming RPC call
org.mortbay.jetty.RetryRequest
at org.mortbay.jetty.nio.SelectChannelConnector$RetryContinuation.suspend(SelectChannelConnector.java:440)
at com.client.application.server.ajax.Continuation4GWT.suspend(Continuation4GWT.java:88)
at com.client.application.server.front.FrontReverseAjaxDispatcher.openPollConnection(FrontReverseAjaxDispatcher.java:112)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at com.google.gwt.user.server.rpc.RPC.invokeAndEncodeResponse(RPC.java:529)
at com.google.gwt.user.server.rpc.RemoteServiceServlet.processCall(RemoteServiceServlet.java:163)
at com.google.gwt.user.server.rpc.RemoteServiceServlet.doPost(RemoteServiceServlet.java:85)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:727)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:820)
at org.mortbay.jetty.servlet.ServletHolder.handle(ServletHolder.java:487)
at org.mortbay.jetty.servlet.ServletHandler.handle(ServletHandler.java:362)
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:726)
at org.mortbay.jetty.webapp.WebAppContext.handle(WebAppContext.java:405)
at org.mortbay.jetty.handler.ContextHandlerCollection.handle(ContextHandlerCollection.java:206)
at org.mortbay.jetty.handler.HandlerCollection.handle(HandlerCollection.java:114)
at org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:152)
at org.mortbay.jetty.Server.handle(Server.java:324)
at org.mortbay.jetty.HttpConnection.handleRequest(HttpConnection.java:505)
at org.mortbay.jetty.HttpConnection$RequestHandler.content(HttpConnection.java:842)
at org.mortbay.jetty.HttpParser.parseNext(HttpParser.java:648)
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)
I'm at a dead end here because the retry exception goes directly to Jetty...
I use the following jars in my webprojet :
jetty-6.1.8.jar
jetty-util-6.1.8.jar
servlet-api-2.5-6.1.8.jar
Any help, ideas or comments would be appreciated a lot on this.
Modified RPC class from GWT 1.5 RC1 to don't catch RetryRequest.
See invokeAndEncodeResponse method.
Hi Raphael,
Looks like you got further towards a solution than I did![]()
Haven't heard anything yet from the core dev team. Guess we'll wait on reply from Jan and then see where we go from here. Sounds like you're as anxious as I am to see this working.
I am being pressed hard to get this working because my project needs it and it would be a huge win for the GWT framework as well.
I'm trying to get a few days freed up to take another look, but I'm probably still going to get horribly confused. Happy to test any patches though!
Cheers,
Tony
Raphael,
Thanks for the code snippet. This is on my to-do list, and I'm trying hard to clear enough time to work on it, but I am just totally snowed under at the moment.
So although I don't have the solution ready, I just wanted to comment to let everyone know that this issue hasn't been forgotten.
Jan
Thanks Jan.
Raphael, sorry I missed your last post where you've attached the RPC.java.
Does this mean you solved the problem? I'm being a bit dim here, but in that code, the RetryRequest isn't dealt with. Surely you have to check for it and rethrow otherwise it will get swallowed by the catch( InvocationTargetException )??
Thanks,
Tony.
Jan,
Thanks for your work on this, and i understand that you might have a lot of things to do first (don't we all have tons of things waiting ?). Let us know as soon as you have an update on this.
Anyway if you have an idea of where it could come from ? Do you think it is in the Jetty implementation, in the HttpServlet, or in Google code ? Because at this point i'm a little confused and i don't really know where to look anymore...
Tony,
Sorry for the first code snippet i provided, the indentation has maded it mostly unreadable.
What i done is exactly what you are describing. In the GWT method invocation in RPC.java i looked for RetryRequest exception in the InvocationTargetException and then rethrows it again.
It is at line 546 in provided RPC.java :
catch (InvocationTargetException e) {
// Try to encode the caught exception
Throwable cause = e.getCause();
if (e.getTargetException() instanceof RetryRequest)
else
{ responsePayload = encodeResponseForFailure(serviceMethod, cause, serializationPolicy); }}
Or maybe i didn't understood right what you were meaning ?
But sure i'm as excited as you are of using jetty with Gwt for doing reverse Ajax ![]()
I'll try to look deeper on this as soon as possible.
A last question : the error log i provided : which class generated it ?
Exception while dispatching incoming RPC call > Isn't it a GWT message ? If i knew where it is crashing maybe i could try to fix it or at least try to understand what is wrong.
Finally after looking more close to it, it seems why solution is lacking at least 2 more things to be working :
throws the retryRequest in the doPost method of RemoteServiceServlet too (~ line 95):
} catch (Throwable e)
{ // Give a subclass a chance to either handle the exception or rethrow it // doUnexpectedFailure(e); }finally
{ // null the thread-locals to avoid holding request/response // perThreadRequest.set(null); perThreadResponse.set(null); }And handle the finally block which could may be problematic.
And i saw on this page http://docs.codehaus.org/display/JETTY/GWT this sample of code which i missed before :
Greg Wilkins said : "Because GWT RPC uses POSTS, the body of the request is consumed when the request is first handled and is not available when the request is retried. To handle this, the parsed contents of the POST are stored as a request attribute so they are available to retried requests without reparsing :"
protected String readPayloadAsUtf8(HttpServletRequest request)
throws IOException, ServletException
{
String payload=(String)request.getAttribute( PAYLOAD );
if ( payload==null )
return payload;
}
I will adapt this portion of code to GWT 1.5 and continue throwing the RetryRequest wich is caught on the doPost method. I'll try this tonight and i'll repost here as soon as i have new information. With a little luck a workaround would be possible ![]()
Hello
I've managed to fix the problem in RemoteServiceServlet.java and RPC.java. I've modified the original classes from GWT implementation, so if you want to use them you will have either to modify youre gwt-servlet.jar to use the new classes, or put them in a package called com.google.gwt.user.server.rpc.
It's working fine for me, the RetryRequest is propagated to the Jetty container, and after timeout or continuation.resume() the request is retried.
I'm attaching the 2 classes as FixedRemoteServiceServlet.java and FixedRPC.java.
Let me know if it's working for you.
Good luck with that
Fixed google classes for using the continuations of jetty 6 with GWT 1.5 RC1
http://docs.codehaus.org/display/JETTY/GWT has been updated.
Note that for jetty7, the RetyRequest has been depcrecated. Its AsyncRemoteServiceServlet impl will be different from jetty6.
Examples are posted on wiki on how to use jetty6 continuations on your service, as well as the servlet-3.0 suspend/resume api for jetty7
gwt 1.5.0-rc1 support for jetty7 is now in trunk.
When using the continuations api, it would still work. But depcrecated.
For the use cases, you can refer to http://docs.codehaus.org/display/JETTY/GWT+RPC+Examples
Thanks for the heads-up Tony. I don't suppose you could attach the relevant srcs from GWT1.5 for me to have a look at?
I might be able to see where the error is and prepare a patch. In general, if you get that exception it means that somehow
the OpenRemoteServiceServlet.doUnexpectedFailure (throwable) method that we override in AsyncRemoteServiceServlet is not being
called.
cheers
Jan