gwtproject / gwt

GWT Open Source Project
http://www.gwtproject.org
1.52k stars 376 forks source link

Polymorphic elements not being loaded via @ExtraTypes using RequestContext #8057

Open dankurka opened 9 years ago

dankurka commented 9 years ago

Originally reported on Google Code with ID 8061

Found in GWT Release (e.g. 2.4.0, 2.5.0 RC):
GWT 2.5.0

Encountered on OS / Browser (e.g. WinXP, IE8-9, FF7):
OpenSuse 12.2 / Firefox 16.0.2

Detailed description (please be as specific as possible):
I have a RequestContext action that retrieves a list of proxy elements of a given type
and subclasses of such type. I could not manage to get in the client the actual sub-classes,
they always happen to be the parent class even including @ExtraTypes annotation in
the RequestContext.

Shortest code snippet which demonstrates issue (please indicate where
actual result differs from expected result):
/**
 * This is the parent server-side entity
 */
public class CompareDiff {

} //end of CompareDiff

/**
 * This is one of the server-side entities that extend the base
 */
public class TimeSchemeValueCompareDiff extends CompareDiff {

} //end of TimeSchemeValueCompareDiff

/**
 * This is a wrapper class that contains a list of elements
 * of the previous types, as well as some other properties.
 */
public class CompareResult {
   private List <CompareDiff> differences = null;

   public List <CompareDiff> getDifferences () {
      return differences;
   }
   public void setDifferences (List <CompareDiff> differences) {
      this.differences = differences;
   }
} //end of CompareResult

/**
 * This is a service that runs some algorithm
 * to finally calculate the result in form of the wrapper
 * containing the list of hybrid elements.
 */
public class CompareService {

   public CompareResult compareVersions () {
      CompareResult result = new CompareResult ();

      result.setDifferences (new ArrayList <CompareDiff> ());
      result.getDifferences ().add (new CompareDiff ());
      result.getDifferences ().add (new TimeSchemeValueCompareDiff ());
   }
} //end of CompareService

/**
 * Client-side proxy for the wrapper
 */
@ProxyFor (value = CompareResult.class)
public interface ICompareResultProxy extends ValueProxy {
   List <ICompareDiffProxy> getDifferences ();
} //end of ICompareResultProxy

/**
 * Client-side proxy for the parent class
 */
@ProxyFor (value = CompareDiff.class)
public interface ICompareDiffProxy extends ValueProxy {

} //end of ICompareDiffProxy

/**
 * Client-side proxy for the child class
 */
@ProxyFor (value = TimeSchemeValueCompareDiff.class)
public interface ITimeSchemeValueCompareDiffProxy extends ICompareDiffProxy {

} //end of ITimeSchemeValueCompareDiffProxy

/**
 * This is the requestContext that invokes the server and retrieves the result.
 */
@ExtraTypes ({ICompareDiffProxy.class, ITimeSchemeValueCompareDiffProxy.class})
@Service (value = CompareService.class, locator = SpringServiceLocator.class)
public interface ICompareRequestContext extends RequestContext {

   Request <ICompareResultProxy> compareVersions (Integer drugVersionID1, Integer drugVersionID2);
} //end of ICompareRequestContext

// finally, the method that gets the list on client-side
requestFactory.getCompareContext ().compareVersions ()
                                   .fire (new Receiver <ICompareResultProxy> () {
   @Override
   public void onSuccess (ICompareResultProxy response) {
      for (ICompareDiffProxy diff : response.getDifferences ()) {
         if (diff instanceof ITimeSchemeValueCompareDiffProxy) {
            System.out.println ("The type identification was perfect !"); //THIS DOES
NOT HAPPEN
         }
      }
   } //end of onSuccess
});

Workaround if you have one:
I followed Mr. Broyer suggestion to my question at SO to debug com.google.web.bindery.requestfactory.server.ResolverServiceLayer#resolveClient‌
and i found deobfuscator.getClientProxies(toSearch.getName()); returned null for the
child proxy, thus forcing it to fall back to its parent proxy. Then, in the generated
IRequestFactoryDeobfuscatorBuilder.java i found no reference to the child entities.
Finally i added a dummy method in the service (and the RequestContext) whose actual
return type is one of the subclasses, and then it works. Something like this:
/** of no use, just to encircle the problem with un-recognized inherited classes */
Request <ITimeSchemeValueCompareDiffProxy> dummyTimeSchemeValueCompareDiff ();

Links to relevant GWT Developer Forum posts:
This is my original question at SO: http://stackoverflow.com/questions/15229306/gwt-polymorphic-lists-with-extratypes

Link to patch posted at http://gwt-code-reviews.appspot.com:

Reported by grodriguez2006 on 2013-03-06 15:34:48

dankurka commented 9 years ago

Reported by t.broyer on 2013-04-30 08:32:15

dankurka commented 9 years ago

Reported by dankurka@google.com on 2013-06-09 14:34:18