Ali
Ali

Reputation: 267137

GWT is unable to instantiate an interface, but can instantiate an abstract class?

If I have the following:

public interface GetItemRequest<T extends FooBase>
{
    public long getId();
}

public class GetFooRequest implements GetItemRequest<Foo>
{
  //snip..
}

public interface GetService extends RemoteService
{
   public <T extends FooBase> T get( GetItemRequest<T> request );
}

And on server, I have the following execute method, which executes the request via GWT-RPC:

public class GetServiceImpl<T extends FooBase>
          extends RemoteServiceServlet
          implements GetSerice<T>

{
   public T get( GetItemRequest<T> request)
   { 
     //snip
   }
}

That does not work, and it gives the error:

Exception: com.google.gwt.user.client.rpc.IncompatibleRemoteServiceException: Invalid type signature for com.xxx.GetFooRequest

However, if I change GetItemRequest to be an abstract class rather than an interface, i.e:

public abstract class GetItemRequest<T extends FooBase>
{
    public abstract long getId();
}

And have GetFooRequest extend from GetItemRequest<Foo> rather than implement it, then the request works just fine.

Strangely however, GetFooRequest must be completely abstract in order for this to work. If I try to implement any method, like getId() in GetItemRequest rather than in GetFooRequest, I get the same exception.

Anyone know the reason behind this strange behavior?

Upvotes: 1

Views: 375

Answers (2)

Braj
Braj

Reputation: 46851

With some changes in your code it will start working:

implements IsSerializable.

import com.google.gwt.user.client.rpc.IsSerializable;
public class GetFooRequest implements GetItemRequest<Foo>,IsSerializable
{
  //snip..
}

change return type.

public class GetServiceImpl<T extends FooBase>
         extends RemoteServiceServlet
         implements GetSerice<T>
  {
     public <T extends FooBase> get( GetItemRequest<T> request)
     { 
       //snip
     }
  }

Upvotes: 1

Braj
Braj

Reputation: 46851

I have tried your code and its working fine with some minor changes.

There are some compilation errors in your code as well, may be due to typo mistake such as:

GetItemRequest<T extends FooBase>

public class GetServiceImpl<T extends FooBase> extends RemoteServiceServlet implements GetService

Please verify it again from below code:

Shared:

public abstract class GetItemRequest<T extends FooBase> {
    public abstract long getId();
}

import com.google.gwt.user.client.rpc.IsSerializable;
public class GetFooRequest  extends GetItemRequest<Foo> implements IsSerializable {
    @Override
    public long getId() {
        return 0;
    }
}

import com.google.gwt.user.client.rpc.IsSerializable;
public class FooBase implements IsSerializable{
    ...
}

public class Foo extends FooBase{
    ...
}

Client:

import com.google.gwt.user.client.rpc.RemoteService;
import com.google.gwt.user.client.rpc.RemoteServiceRelativePath;
import com.gwt.test.shared.FooBase;
import com.gwt.test.shared.GetItemRequest;
@RemoteServiceRelativePath("get")
public interface GetService extends RemoteService {
    public <T extends FooBase> T get(GetItemRequest<T> request);
}

import com.google.gwt.user.client.rpc.AsyncCallback;
import com.gwt.test.shared.FooBase;
import com.gwt.test.shared.GetItemRequest;
public interface GetServiceAsync {
    void get(GetItemRequest request, AsyncCallback<FooBase> callback);
}

public void onModuleLoad() {

    GetServiceAsync getService = GWT.create(GetService.class);

    getService.get(new GetFooRequest(), new AsyncCallback<FooBase>() {

        @Override
        public void onFailure(Throwable caught) {
            System.out.println("failure");
        }

        @Override
        public void onSuccess(FooBase result) {
            System.out.println("success");
        }

    });

    ...
}

Server:

import com.google.gwt.user.server.rpc.RemoteServiceServlet;
import com.gwt.test.client.GetService;
import com.gwt.test.shared.Foo;
import com.gwt.test.shared.FooBase;
import com.gwt.test.shared.GetItemRequest;
public class GetServiceImpl<T extends FooBase> extends RemoteServiceServlet implements GetService {
    @Override
    public <T extends FooBase> T get(GetItemRequest<T> request) {
        ...
    }
}

web.xml:

  <servlet>
    <servlet-name>getServlet</servlet-name>
    <servlet-class>com.x.y.z.server.GetServiceImpl</servlet-class>
  </servlet>

  <servlet-mapping>
    <servlet-name>getServlet</servlet-name>
    <url-pattern>/context_root/get</url-pattern>
  </servlet-mapping>

Upvotes: 1

Related Questions