How can i create a method that accepts Class and Field as parameters? Like this:
List<SomeClassEntity> list = ...;
// Service to make useful things around a list of objects
UsefulThingsService<SomeClassEntity> usefulThingsService = new UsefulThingsService<>();
// Maybe invoke like this. Did't work
usefulThingsService.makeUsefulThings(list, SomeClassEntity.class, SomeClassEntity::getFieldOne);
// or like this. Will cause delayed runtime erros
usefulThingsService.makeUsefulThings(list, SomeClassEntity.class, "fieldTwo");
public class SomeClassEntity {
Integer fieldOne = 10;
Double fieldThree = 0.123;
public Integer getFieldOne() {
return fieldOne;
}
public void setFieldOne(Integer fieldOne) {
this.fieldOne = fieldOne;
}
public Double getFieldThree() {
return fieldThree;
}
public void setFieldThree(Double fieldThree) {
this.fieldThree = fieldThree;
}
}
public class UsefulThingsService<T> {
public void makeUsefulThings(Class<T> someClassBClass, String fieldName) {
// there is some code
}
}
Want to have correct references on compile stage, not at runtime.
Update:
I need code that would look more convenient than this:
Field fieldOne = null;
try {
fieldOne = SomeClassEntity.class.getDeclaredField("fieldOne");
} catch (NoSuchFieldException e) {
e.printStackTrace();
}
usefulThingsService.makeUsefulThings(SomeClassEntity.class, fieldOne);
I apologize for the next clarification.
Update 2:
- The service compares the list with the previous list, reveals only the changed fields of objects (list items) and updates these fields in the objects in the original list.
- Currently i use annotation on entity's field that is actually ID of the entity and that ID is used to detect identically entities (old and new) when i need to update field of entity in source list.
- Service detect annotated field and use it for next update process.
- I want to refuse to use annotations and provide an Field directly in constructor of service. Or use something other that could establish a relationship between class and field on compilation stage.
Assuming that you want field access because you want to get and set the value, you’d need two functions:
public class UsefulThingsService<T> {
public <V> void makeUsefulThings(List<T> list, Function<T,V> get, BiConsumer<T,V> set) {
for(T object: list) {
V v = get.apply(object);
// there is some code
set.accept(object, v);
}
}
}
and
usefulThingsService.makeUsefulThings(
list, SomeClassEntity::getFieldOne, SomeClassEntity::setFieldOne);
usefulThingsService.makeUsefulThings(
list, SomeClassEntity::getFieldThree, SomeClassEntity::setFieldThree);
There are, however, some things open. E.g., how is this service supposed to do something useful with the field resp. property, without even knowing its actual type. In your example, both are subtypes of Number, so you could declare <V extends Number>, so the method knows how to extract numerical values, however, constructing an appropriate result object would require specifying another function argument.
Related
I have two ArrayLists - ArrayList1 and ArrayList2. Each of them is filled with objects - Object1 and Object2, respectively.
Both of these objects have method 'getText'.
Object1:
public String getText() { return "1";}
Object2:
public String getText() { return "2";}
At certain point I would like to loop through each of these lists using the same method (just with different parameter).
loopThroughList(1)
loopThroughList(2)
What is the syntax if I want to call a method, but I don't know which object it is going to be? This is the code I have so far:
for (Object o : lists.getList(listNumber)) {
System.out.println(o.getText());
}
It says Cannot resolve method getText. I googled around and found another solution:
for (Object o : lists.getList(listNumber)) {
System.out.println(o.getClass().getMethod("getText"));
}
But this gives me NoSuchMethodException error. Even though the 'getText' method is public.
EDIT: To get the correct list, I am calling the method 'getList' of a different object (lists) that returns either ArrayList1 or ArrayList2 (depending on the provided parameter).
class Lists
public getList(list) {
if (list == 1) {
return ArrayList1;
}
else if (list == 2) {
return ArrayList2;
}
}
Define an interface for the getText method
public interface YourInterface {
String getText();
}
Implement the interface on the respective classes
public class Object1 implements YourInterface {
#Override
public String getText() {
return "1";
}
}
public class Object2 implements YourInterface {
#Override
public String getText() {
return "2";
}
}
Modify your getList method to return List<YourInterface>
public static List<YourInterface> getList(int list){
List<YourInterface> result = new ArrayList<>();
if(list == 1){
// your initial type
List<Object1> firstList = new ArrayList<>();
result.addAll(firstList);
} else {
// your initial type
List<Object2> secondList = new ArrayList<>();
result.addAll(secondList);
}
return result;
}
Declaration for loopThroughList
public static void loopThroughList(List<YourInterface> list){
list.forEach(yourInterface -> System.out.println(yourInterface.getText()));
}
Sample usage.
public static void main(String[] args) {
loopThroughList(getList(1));
loopThroughList(getList(2));
}
Interfaces work great here, but there a couple of other options if you're dealing with legacy code and cannot use interfaces.
First would be to cast the list items into their respective types:
for (Object o : lists.getList(listNumber)) {
if(o instanceof Object1) {
Object1 o1 = (Object1)o;
System.out.println(o1.getText());
}
else if(o instanceof Object2) {
Object1 o2 = (Object2)o;
System.out.println(o2.getText());
}
else {
System.out.println("Unknown class");
}
}
You can also use reflection to see if the object has a getText method and then invoke it:
for (Object o : lists.getList(listNumber)) {
try {
System.out.println(o.getClass().getDeclaredMethod("getName").invoke(o));
}
catch(Exception e) {
System.out.println("Object doesn't have getText method");
}
}
This is awful. Can you elaborate on what specifically you are trying to do? Java is strong typed by design, and you are trying to get around it. Why? Instead of Object, use the specific class, or interface as previously suggested. If that's not possible, and you must use lists of Objects, use instanceof and casting eg:
for (Object o : lists.getList(listNumber)) {
if (o instanceof Object1) {
Object1 o1 = (Object1) o;
System.out.println(o1.getText());
} else if (o instanceof Object2) {
Object2 o2 = (Object2) o;
System.out.println(o2.getText());
}
}
This is where interfaces come in.
interface HasText {
public String getText();
}
class Object1 implements HasText {
#Override
public String getText() {
return "1";
}
}
class Object2 implements HasText {
#Override
public String getText() {
return "2";
}
}
private void test() {
List<HasText> list = Arrays.asList(new Object1(), new Object2());
for (HasText ht : list) {
System.out.println(ht);
}
}
If one of your objects is not in your control you can use a Wrapper class.
class Object3DoesNotImplementHasText {
public String getText() {
return "3";
}
}
class Object3Wrapper implements HasText{
final Object3DoesNotImplementHasText it;
public Object3Wrapper(Object3DoesNotImplementHasText it) {
this.it = it;
}
#Override
public String getText() {
return it.getText();
}
}
private void test() {
List<HasText> list = Arrays.asList(new Object1(), new Object2(), new Object3Wrapper(new Object3DoesNotImplementHasText()));
for (HasText ht : list) {
System.out.println(ht);
}
}
Just to add more to this answer and give you some more to think on this (Will try to do it in a simple, non-formal way). Using interfaces is the proper way of doing such operation. However, I want to stand on the "bad idea":
for (Object o : lists.getList(listNumber)) {
System.out.println(o.getClass().getMethod("getText"));
}
What you are doing here, is using a mechanism called Reflection:
Reflection is a feature in the Java programming language. It allows an
executing Java program to examine or "introspect" upon itself, and
manipulate internal properties of the program. For example, it's
possible for a Java class to obtain the names of all its members and
display them.
What you actually attempted, is using that mechanism, to retrieve the method through a Class reflection object instance of your Class (sounds weird, isn't it?).
From that perspective, you need to think that, if you want to invoke your method, you now have, in a sense, a meta-Class instance to manipulate your objects. Think of it like an Object that is one step above your Objects (Similarly to a dream inside a dream, in Inception). In that sense, you need to retrieve the method, and then invoke it in a different (meta-like) way:
java.lang.reflect.Method m = o.getClass().getMethod("getText");
m.invoke(o);
Using that logic, you could possibly iterate through the object list, check if method exists, then invoke your method.
This is though a bad, BAD idea.
Why? Well, the answer relies on reflection itself: reflection is directly associated with runtime - i.e. when the program executes, practically doing all things at runtime, bypassing the compilation world.
In other words, by doing this, you are bypassing the compilation error mechanism of Java, allowing such errors happen in runtime. This can lead to unstable behavior of the program while executing - apart from the performance overhead using Reflection, which will not analyze here.
Side note: While using reflection will require the usage of Checked Exception handling, it still is not a good idea of doing this - as you practically try to duck tape a bad solution.
On the other hand, you can follow the Inheritance mechanism of Java through Classes and Interfaces - define an interface with your method (let's call it Textable), make sure that your classes implement it, and then use it as your base object in your list declaration (#alexrolea has implemented this in his answer, as also #OldCurmudgeon has).
This way, your program will still make the method call decision making at Runtime (via a mechanism called late binding), but you will not bypass the compilation error mechanism of Java. Think about it: what would happen if you define a Textable implementation without providing the class - a compile error! And what if you set a non-Textable object into the list of Textables? Guess what! A compile error again. And the list goes on....
In general, avoid using Reflection when you are able to do so. Reflection is useful in some cases that you need to handle your program in such a meta-way and there is no other way of making such things. This is not the case though.
UPDATE: As suggested by some answers, you can use instanceof to check if you have a specific Class object instance that contains your method, then invoke respectively. While this seems a simple solution, it is bad in terms of scaling: what if you have 1000 different classes that implement the same method you want to call?
your objects have to implement a common interface.
interface GetTextable {
String getText();
}
class One implements GetTextable {
private final String text;
public One(final String text) {
this.text = text;
}
public String getText() {
return this.text;
}
}
class Two implements GetTextable {
private final String text;
public Two(final String text) {
this.text = text;
}
public String getText() {
return this.text;
}
}
#Test
public void shouldIterate() throws Exception {
List<GetTextable> toIterate = Arrays.asList(new One("oneText"), new Two("twoText"));
for(GetTextable obj: toIterate) {
System.out.println(obj.getText());
}
}
So my problem is that im currently trying to use java's reflection to traverse a tree like structure. The problem is the only thing i know about each structure is that it can contain one of three things. Strings (the leaf's) Other Objects, Or Lists of other objects. Using reflection i want to do a DFS of the tree until i find a node that im looking for. My problem seems to be that when i use reflection to get a field that happens to be of type List i get back List and i am unable to down cast the the correct type. here are some samples i have tried.
Using Fields
Object returnObj = new Object();
Field field = object.getClass().getDeclaredField(fieldClassName);
field.setAccessible(true);
List<DistributionPartnerRoleType> test = (List<DistributionPartnerRoleType>) field.get(object);
And using Methods
String methodName = "get" + Character.toUpperCase(fieldClassName.charAt(0)) + fieldClassName.substring(1);
Method[] getters = object.getClass().getMethods();
Method getter = getMethod(getters, methodName);
Type returnType = getter.getGenericReturnType();
if(returnType instanceof ParameterizedType){
Type actualType = ((ParameterizedType) returnType).getActualTypeArguments()[0];
Class actualClass = (Class) actualType;
returnObj = getter.invoke(object, null);
List<Object> newList = new ArrayList<Object>();
for(Object obj : (List<Object>)returnObj){
newList.add(actualClass.cast(obj));
}
returnObj = newList;
}
Im aware that the problem is that the objects are truly of type Object but the function and fields are explicitly of type List as declared in the code
protected List<DistributionPartnerRoleType> distributionPartnerRole;
public List<DistributionPartnerRoleType> getDistributionPartnerRole() {
if (distributionPartnerRole == null) {
distributionPartnerRole = new ArrayList<DistributionPartnerRoleType>();
}
return this.distributionPartnerRole;
}
If anyone knows of a solution for this problem that would be great, Or if i need to go about a different method other then reflection.
To sum up my problem. Invoke is returning a List But the objects inside the list are not actually of the type this function returns they are of type java.lang.Object Is there any way to get around this or is dynamic access of the lists objects not possible?
I don't think use of reflection is a good idea in this case. In my view there are very few appropriate use cases. It's often a sign that you need to rethink your approach.
In this case I suggest you look at the Visitor design pattern. The visitor itself can include the logic for a depth-first search as well as dealing with the various types of data in the nodes.
In your case the pattern might look something like:
interface Node {
void accept(NodeVisitor visitor);
}
class StringNode implements Node {
public String getValue();
public void accept(NodeVisitor visitor) {
visitor.visit(this);
}
}
class IntegerNode implements Node {
public int geValue();
public void accept(NodeVisitor visitor) {
visitor.visit(this);
}
}
class CompositeNode implements Node {
public void forEachChild(Consumer<Node> action);
public void accept(NodeVisitor visitor) {
visitor.visit(this);
}
}
interface NodeVisitor {
default void visit(StringNode node) {}
default void visit(IntegerNode node) {}
default void visit(CompositeNode node) {}
}
Now your search algorithm might look like:
class IntegerSearch implements NodeVisitor {
private final int target;
private final List<IntegerNode> results = new ArrayList<>();
void visit(IntegerNode node) {
if (node.getValue() == target)
results.add(node);
}
}
void visit(CompositeNode node) {
node.forEachChild(child -> child.accept(this));
}
}
No reflection, casting or other dodgy idioms!
This might not exactly match your case (e.g. perhaps the nodes with values are also composites?) but hopefully you see the general pattern for avoiding reflection.
There is a deeper problem here, As stated by Louis Wasserman, reflection should not be causing this and there seems to be a problem with my code in another location.
I have an object which has a few arrays as fields. It's class roughly looks like this:
public class Helper {
InsuranceInvoices[] insuranceInvoices;
InsuranceCollectiveInvoices[] insuranceCollectiveInvoices
BankInvoices[] bankInvoices;
BankCollectiveInvoices[] bankCollectiveInvoices;
}
All of the invoice types have a mutual marker interface Invoices.
I need to get all of the invoices to invoke another method on them.
Helper helperObject = new Helper();
// ...
for (InsuranceInvoices invoice : helperObject.getInsuranceInvoices()) {
Integer customerId = invoice.getCustomerId();
// ...
}
for (BankInvoices invoice : helperObject.getBankInvoices()) {
Integer customerId = invoice.getCustomerId();
// ...
}
// repeat with all array fields
The problem is that all invoices only have the marker interface in common. The method getCustomerID() is not defined by a mutual interface or class. This is a behaviour I cannot change due to a given specification.
The code repetition inside the for-each-loop is something that bugs me. I have to do the exact same thing on all invoice objects in the four different arrays. Hence four for-each-loops that unecessary bloat the code.
Is there a way that I can write a general (private) method? One idea was:
private void generalMethod(Invoice[] invoiceArray){
// ...
}
But this would require four instanceof checks because the class Invoice doesn't know the method getCusomterId(). Therefore I would gain nothing; the method would still contain repetitions.
I'm thankful for every possible solution to generalize this problem!
Possible solutions to generalize the problem (ordered from best to worst):
Using wrapper class
public class InvoiceWrapper {
private String customerID;
public String getCustomerID() {
return customerID;
}
public InvoiceWrapper(BankInvoices invoice) {
this.customerID = invoice.getCustomerID();
}
public InvoiceWrapper(InsuranceInvoices invoice) {
this.customerID = invoice.getCustomerID();
}
// other constructors
}
Upd If I understood correctly, you need to do something with IDs in all arrays. To use InvoiceWrapper, you also need to implement iterator in Helper class, that will walk through arrays and return a wrapper for each entry. So, you will have code that works with 4 arrays anyway.
Using instance of casts
public class CustomerIdHelper {
public static String getID(Invoice invoice) {
if (invoice instanceof InsuranceInvoices) {
return ((InsuranceInvoices) invoices).getCustomerID();
} else if ...
}
}
Calling methods by name via Reflection
public class CustomerIdHelper {
public static String getID(Invoice invoice) {
Method method = invoice.getClass().getDeclaredMethod("getCustomerId");
return (String) method.invoke(invoice);
}
}
It's not pretty, but you could use reflection to look up the getCustomerId Method and then invoke() it, cf. Class.getDeclaredMethod().
private void generalMethod(Invoice[] invoiceArray){
try {
for (Invoice invoice : invoiceArray) {
Method getCustomerId = invoice.getClass().getDeclaredMethod("getCustomerId");
getCustomerId.invoke(invoice);
}
} catch (Exception e) {
// ...
}
}
Do note that this is untested.
If you are not allowed to change the classes you are handling by adding a custom interface to them. The best thing you can do is wrap them with a custom class that does have the desired properties.
This way you will have one class with all 'not so nice' code that converts the classes you can not touch to nice classes that match a proper and useful design.
For instance you could have a class WrappedInsuranceInvoice that extends WrappedInsurace and contains a member field InsuranceInvoice. If you don't need to keep the original class you would be off even better by copying the data. This way you could for instance lose the arrays and use lists instead.
Let's say I have a manufacturing scheduling system, which is made up of four parts:
There are factories that can manufacture a certain type of product and know if they are busy:
interface Factory<ProductType> {
void buildProduct(ProductType product);
boolean isBusy();
}
There is a set of different products, which (among other things) know in which factory they are built:
interface Product<ActualProductType extends Product<ActualProductType>> {
Factory<ActualProductType> getFactory();
}
Then there is an ordering system that can generate requests for products to be built:
interface OrderSystem {
Product<?> getNextProduct();
}
Finally, there's a dispatcher that grabs the orders and maintains a work-queue for each factory:
class Dispatcher {
Map<Factory<?>, Queue<Product<?>>> workQueues
= new HashMap<Factory<?>, Queue<Product<?>>>();
public void addNextOrder(OrderSystem orderSystem) {
Product<?> nextProduct = orderSystem.getNextProduct();
workQueues.get(nextProduct.getFactory()).add(nextProduct);
}
public void assignWork() {
for (Factory<?> factory: workQueues.keySet())
if (!factory.isBusy())
factory.buildProduct(workQueues.get(factory).poll());
}
}
Disclaimer: This code is merely an example and has several bugs (check if factory exists as a key in workQueues missing, ...) and is highly non-optimal (could iterate over entryset instead of keyset, ...)
Now the question:
The last line in the Dispatcher (factory.buildProduct(workqueues.get(factory).poll());) throws this compile-error:
The method buildProduct(capture#5-of ?) in the type Factory<capture#5-of ?> is not applicable for the arguments (Product<capture#7-of ?>)
I've been racking my brain over how to fix this in a type-safe way, but my Generics-skills have failed me here...
Changing it to the following, for example, doesn't help either:
public void assignWork() {
for (Factory<?> factory: workQueues.keySet())
if (!factory.isBusy()) {
Product<?> product = workQueues.get(factory).poll();
product.getFactory().buildProduct(product);
}
}
Even though in this case it should be clear that this is ok...
I guess I could add a "buildMe()" function to every Product that calls factory.buildProduct(this), but I have a hard time believing that this should be my most elegant solution.
Any ideas?
EDIT:
A quick example for an implementation of Product and Factory:
class Widget implements Product<Widget> {
public String color;
#Override
public Factory<Widget> getFactory() {
return WidgetFactory.INSTANCE;
}
}
class WidgetFactory implements Factory<Widget> {
static final INSTANCE = new WidgetFactory();
#Override
public void buildProduct(Widget product) {
// Build the widget of the given color (product.color)
}
#Override
public boolean isBusy() {
return false; // It's really quick to make this widget
}
}
Your code is weird.
Your problem is that you are passing A Product<?> to a method which expects a ProductType which is actually T.
Also I have no idea what Product is as you don't mention its definition in the OP.
You need to pass a Product<?> to work. I don't know where you will get it as I can not understand what you are trying to do with your code
Map<Factory<?>, Queue<Product<?>>> workQueues = new HashMap<Factory<?>, Queue<Product<?>>>();
// factory has the type "Factory of ?"
for (Factory<?> factory: workqueues.keySet())
// the queue is of type "Queue of Product of ?"
Queue<Product<?>> q = workqueues.get(factory);
// thus you put a "Product of ?" into a method that expects a "?"
// the compiler can't do anything with that.
factory.buildProduct(q.poll());
}
Got it! Thanks to meriton who answered this version of the question:
How to replace run-time instanceof check with compile-time generics validation
I need to baby-step the compiler through the product.getFactory().buildProduct(product)-part by doing this in a separate generic function. Here are the changes that I needed to make to the code to get it to work (what a mess):
Be more specific about the OrderSystem:
interface OrderSystem {
<ProductType extends Product<ProductType>> ProductType getNextProduct();
}
Define my own, more strongly typed queue to hold the products:
#SuppressWarnings("serial")
class MyQueue<T extends Product<T>> extends LinkedList<T> {};
And finally, changing the Dispatcher to this beast:
class Dispatcher {
Map<Factory<?>, MyQueue<?>> workQueues = new HashMap<Factory<?>, MyQueue<?>>();
#SuppressWarnings("unchecked")
public <ProductType extends Product<ProductType>> void addNextOrder(OrderSystem orderSystem) {
ProductType nextProduct = orderSystem.getNextProduct();
MyQueue<ProductType> myQueue = (MyQueue<ProductType>) workQueues.get(nextProduct.getFactory());
myQueue.add(nextProduct);
}
public void assignWork() {
for (Factory<?> factory: workQueues.keySet())
if (!factory.isBusy())
buildProduct(workQueues.get(factory).poll());
}
public <ProductType extends Product<ProductType>> void buildProduct(ProductType product) {
product.getFactory().buildProduct(product);
}
}
Notice all the generic functions, especially the last one. Also notice, that I can NOT inline this function back into my for loop as I did in the original question.
Also note, that the #SuppressWarnings("unchecked") annotation on the addNextOrder() function is needed for the typecast of the queue, not some Product object. Since I only call "add" on this queue, which, after compilation and type-erasure, stores all elements simply as objects, this should not result in any run-time casting exceptions, ever. (Please do correct me if this is wrong!)
i am learning GWT.
I got a error regarding the serilizablity.
breif discription of my problem
In class Customproperties
package com.exp.shared;
import java.io.Serializable;
import java.util.List;
public class Customproperties implements Serializable {
private Object value;
private List<?> values;
// more variable
public Customproperties() {
// TODO Auto-generated constructor stub
}
public Customproperties(String propertyName, List<?> object,
String propertyType, boolean mulitiValued, String cardinality, Boolean required) {
this.propertyName=propertyName;
this.values=object;
// more initialization
}
public Customproperties(String propertyName, List<?> object, String propertyType,
boolean multiValued) {
this.propertyName=propertyName;
this.values=object;
// more initialization
}
public Object getValue() {
return value;
}
public List<?> getValues() {
return values;
}
}
In server package in one of the classImpl i am using a object of Customproperties
if (doc.getPropertyValue("cmis:objectTypeId").toString().equals("cmis:document")) {
customproperty=new Customproperties(p.getDefinition().getDisplayName(), p.getValue(), p.getType().toString(),p.isMultiValued());
}
else {
customproperty=new Customproperties(p.getDefinition().getDisplayName(), p.getValues(), p.getType().toString(),p.isMultiValued(),value.getCardinality(),value.isRequired());
}
here in if condntion p.getValue() returns Object.
and in else condition p.getValues() returns List.
in CustomProperties class when i change the object variable to string it is working perfectly fine.
but i dont change it it gives me error.
com.exp.shared.Customproperties' was not included in the set of types which can be serialized by this SerializationPolicy or its Class object could not be loaded. For security purposes, this type will not be serialized.: instance = com.exp.shared.Customproperties#1aa5344
at com.google.gwt.user.server.rpc.impl.ServerSerializationStreamWriter.serialize(ServerSerializationStreamWriter.java:619)
I dont want to change it String . i just want to receive Object. cause this object can be some times String, date, int.
Plzz help.
You should read the GWT docs about RPC serialization here.
The class java.lang.Object is not serializable, therefore you cannot expect that a collection of Object types will be serialized across the wire.
This is why you get your exception. In the code you've given, you're not using the field value. Both constructors on your class only set the values list. So if you're not using the field value, just remove it and it will work. But assuming that's a mistake and you do need to use it ...
You will have to know all the different possible types your value can have. And then either you have different fields, like intValue, dateValue, stringValue ...
Or you can have one String field, and serialize your objects into strings like this.
public class CustomProperties {
private String value;
private String type;
private void setValue(Object value, String type) {
if (value != null) {
this.value = value.toString();
this.type = type;
}
}
private Object getValue() {
if (value != null) {
if ("int".equals(type)) return Integer.valueOf(value);
elseif ("date".equals(type)) return // Parse date from value here
elseif ("string".equals(type)) return (String) value;
// other cases
}
return value;
}
}
In GWT when declaring containers never declare generic types like List.
Always use the more specific types like ArrayList.
In your case, the problem is most likely the List<?>. GWT doesnt know what possible types you are putting in that list, so instead of generating code to serialize every single possible type on the sourcepath, it generates nothing except for what it knows it already needs. When you attempt to put something in there that wasn't needed elsewhere, the exception occurs, indicating that GWT wasn't told that you planned on sending that object over the wire.
A standard approach here is usually to create a marker interface that probably implements Serializable, and make it a List<MyModelObjects>. Then every object that can fit in there should implement that interface.