Home > Gwt, Java > It’s tough to overload our GWT RPC

It’s tough to overload our GWT RPC

Actually, it wasn’t too bad once I worked through how I wanted to load test a GWT app. We have lots of tests for the GUI portion which obviously also test the RPC/server side; but we wanted to really stress test a few RPC paths.

Fortunately, we are not the first. We needed a mechanism to simulate RPC calls and with a little digging (actually, it was pretty hidden in a mess of less than helpful posts), we found a rough and ready class that we used – easier to borrow something than to build from scratch. Here is the project page:

http://code.google.com/p/gwt-syncproxy/

Once we adapted the code to our specific case and removed the app engine stuff, we were good to go with a quick framework that lets us write RPC test cases that look like:

RPCService service = 
       (RPCService ) SyncProxy.newProxyInstance(RPCService.class, 
                                                "http://mydomain/my-web-app/",
                                                "path");
String result = service.executeRemoteMethod(param1, param2);

We use the SyncProxy to instantiate the RPC service, than call a method on the service interface and wait for the result. That’s my definition of easy to use. The great thing is the test code is synchronized so we don’t have to worry about ansyc calls in the test code and can evaluate the result for correctness immediately.

Next up is to use Apache JMeter to simulate load. This again is relatively easy. By implementing the JavaSamplerClient of JMeter, we can add our test case as a java class that gets executed. There is sample code available – take a look at SleepTest included in the source download.

We did have to modify the source code to add the ability to include the CookieManager in the JavaSamplerClient. This required a bit more digging around and modifying of JMeter but is doable in an hour or so and changes 3-4 JMeter files in the java protocol package. If you want to do this, look at the HTTP protocol package. We did this because our code retrieves cookies via a standard HTTP call first and then calls our java test case which needs to access the cookies. Other than that, we used the stock framework and can easily load test our app.

In fact, with these two pieces (SyncProxy and JavaSamplerClient) we quickly write test cases for the critical parts of our app that we want to load test. That’s my task for next week – yeah!

The great part is after a day of testing different components, our performance and scalability is even greater than what we thought it was (ok we did make one minor change to remove some contention) and we have lots of room for growth with our current architecture.

The only part I couldn’t figure out was how to get JMeter to add our jar files to it’s internal classpath. We tried using the search_paths and user.classpath parameters, but nothing we did seemed to allow JMeter to pickup our jars from a different location. It’s just an annoyance to have to build the components and then move the jars to the ext directory of JMeter. Would be nice if we could get the search_paths parameter working. Oh well, maybe another day.

All in all, it took about a day to become familiar with these tools and write our test cases to cover our most frequently used code paths.

 
Categories: Gwt, Java
  1. Ray Tayek
    November 7th, 2010 at 12:44 | #1

    hi, having problems with htmlunit trying to test a gwt rpc, so i found your post.

    i commented out the loginGAE() method in SyncProxy and am getting an exception (Exception while invoking the remote service p.client.GreetingService.greetServer) thrown in RemoteServiceInvocationHandler.

    this is using new project made gwt 2.1 in eclipse. i am running on localhost in dev mode.

    any pointers will be appreciated.

    thanks

  2. Chris Hane
    November 8th, 2010 at 13:38 | #2

    Ray,

    From what I remember (and reading the post again), the SyncProxy is built to be used with GAE. We basically forked the project internally and ripped out all of the GAE code. And the loginGAE method was one of those things. It took a little bit; but from what I remember, it wasn’t too hard. We did it quickly and used trial and error to remove the GAE specifics.

    If you are getting an exception than you did not rip it out completely. The code is still making a call (probably in the client side of the proxy) to that method.

    Hopefully this will put you on the right path. I would do a global search for loginGAE in your local copy of the Sync Proxy code.

    Good luck.

  3. Ernesto Carrion
    December 16th, 2010 at 11:09 | #3

    Hello,

    It seems that the rpc call is failling when returning a Custom object (Class that wrap 2 string and one integer), when the rcp returns a string it works fine, but with the first case I’m getting this :

    Exception while invoking the remote service co.com.sura.soatvl.client.services.IConsultasService.consultarTexto
    com.google.gwt.user.client.rpc.InvocationException: Exception while invoking the remote service co.com.sura.soatvl.client.services.IConsultasService.consultarTexto
    at com.gdevelop.gwt.syncrpc.RemoteServiceInvocationHandler.invoke(RemoteServiceInvocationHandler.java:185)
    at $Proxy0.consultarTexto(Unknown Source)
    at co.com.sura.soatvl.client.StressTest.loadRPC(StressTest.java:33)
    at co.com.sura.soatvl.client.StressTest.main(StressTest.java:46)
    Caused by: com.google.gwt.user.client.rpc.InvocationException: Error while performing serialization
    at com.gdevelop.gwt.syncrpc.RemoteServiceSyncProxy.doInvoke(RemoteServiceSyncProxy.java:169)
    at com.gdevelop.gwt.syncrpc.RemoteServiceInvocationHandler.invoke(RemoteServiceInvocationHandler.java:164)
    … 3 more
    Caused by: com.google.gwt.user.client.rpc.SerializationException: Type ‘co.com.sura.soatvl.shared.dto.Texto’ was not included in the set of types which can be deserialized by this SerializationPolicy or its Class object could not be loaded. For security purposes, this type will not be deserialized.
    at com.google.gwt.user.server.rpc.impl.StandardSerializationPolicy.validateDeserialize(StandardSerializationPolicy.java:158)
    at com.gdevelop.gwt.syncrpc.SyncClientSerializationStreamReader.deserialize(SyncClientSerializationStreamReader.java:360)
    at com.google.gwt.user.client.rpc.impl.AbstractSerializationStreamReader.readObject(AbstractSerializationStreamReader.java:119)
    at com.google.gwt.user.client.rpc.impl.RequestCallbackAdapter$ResponseReader$8.read(RequestCallbackAdapter.java:104)
    at com.gdevelop.gwt.syncrpc.RemoteServiceSyncProxy.doInvoke(RemoteServiceSyncProxy.java:158)
    … 4 more

    Do you know what I’m doing wrong and how and how to fix it? ;)

    Thanks in advance.

  4. Chris Hane
    December 16th, 2010 at 15:55 | #4

    @Ernesto Carrion
    Without seeing the code I’m not sure. I would guess you are trying to serialize something that can’t be serialized.

    I would encourage you to ask on the GWT user forums. There are a lot more eyes there. Don’t forget to include some more context – actual code snippets work best.

  5. Ernesto Carrion
    December 17th, 2010 at 08:24 | #5

    @Chris Hane

    The problem seems to be that my class have permission to serialize but no to deserialize.
    I found this on my *.gwt.rpc.

    co.com.sura.soatvl.shared.dto.Texto, true, true, false, false, co.com.sura.soatvl.shared.dto.Texto/2912884571, 2912884571

    My workaround was to change all of those false to true, but I don´t know how safe/unsafe is that.

    BTW I’m using GWT 2.1

    PS: Thanks for your response.

  1. No trackbacks yet.

Spam Protection by WP-SpamFree