Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the effect of reverse proxy on a GWT application?

I am deploying a GWT 2.4 app on Glassfish 3.0.1. I can easily access my application via http://host:PORT/appContext/
However, when I reverse proxy the application with Apache I get an exception with the following excerpt (from Glassfish logs):

Exception while dispatching incoming RPC call com.google.gwt.user.client.rpc.SerializationException: Type 'com.ozdokmeci.basicgwtproject.shared.GroupData' was not assignable to 'com.google.gwt.user.client.rpc.IsSerializable' and did not have a custom field serializer. For security purposes, this type will not be serialized.

Implementing IsSerializable solves the problem as advised by Chi in a related question. There are also other workarounds in the related question.

My question is what is the underlying cause of this and how come two seemingly unrelated solutions (implementing a marker interface and extending a servlet class) solve this problem? Also are there any disadvantages to both of the methods mentioned in the related question?

Note: The exception does not occur if the app is reached directly.

Note2: Class related to the exception already implements the interface Serializable, which should be equivalent to the IsSerializable as far as GWT is concerned.

like image 552
Kaan Avatar asked Sep 30 '11 13:09

Kaan


1 Answers

I had the exact same issue and when I traced through the source code I found that the directory of GWT serialization files was not being found when reverse-proxying (I think because the directory was a relative path). This is why you are getting serialization exceptions even though you have implemented IsSerializable.

My solution in the end was to move to restful JSON for my RPC. Using JSON will allow you to reverse proxy because it doesnt need to find these Serialization files.

Edit

If you want to still use GWT RPC though, I have an idea of how it's possible (though I havent implemented it myself).

First, take a look at the GWT Help about these rpc files: https://developers.google.com/web-toolkit/doc/2.4/DevGuideCompilingAndDebugging#key_application_files

You will notice it says:

The serialization policy file must be accessible by your RPC RemoteServiceServlet via the ServletContext.getResource() call

So you will need to override RemoteServiceServlet and re-point the location of the rpc (serialization policy) files.

Here is one suggestion, taken from this site: http://code.google.com/p/google-web-toolkit/issues/detail?id=4817

    public class MyRemoteServiceServlet extends RemoteServiceServlet
    {

    ...

    @Override
    protected SerializationPolicy doGetSerializationPolicy(
            HttpServletRequest request, String moduleBaseURL, String strongName) {
            //get the base url from the header instead of the body this way 
            //apache reverse proxy with rewrite on the header can work
            String moduleBaseURLHdr = request.getHeader("X-GWT-Module-Base");

            if(moduleBaseURLHdr != null){
                    moduleBaseURL = moduleBaseURLHdr;
            }

            return super.doGetSerializationPolicy(request, moduleBaseURL, strongName);
    }

    ...

In apache config add:

    ProxyPass /app/ ajp://localhost:8009/App-0.0.1-SNAPSHOT/

    <Location /app/>

    RequestHeader edit X-GWT-Module-Base ^(.*)/app/(.*)$ $1/App-0.0.1-SNAPSHOT/$2

    </Location>

Hopefully my suggestion above at least points someone in the right direction. Please let us know if someone implements this and it works.

like image 85
jasop Avatar answered Nov 15 '22 15:11

jasop