Open GoogleCodeExporter opened 9 years ago
The core problem is that we inspect the fields of the declared type, not the
InstanceCreator-created type.
Original comment by limpbizkit
on 11 Apr 2012 at 8:50
if the interface defines setters has the same problem anyway.
Original comment by roc...@gmail.com
on 18 Apr 2012 at 3:35
This fails in 2.1 and 2.0.
Works fine in 1.7.2 though.
Original comment by future...@gmail.com
on 30 Apr 2012 at 10:03
Same problem.
"The core problem is that we inspect the fields of the declared type, not the
InstanceCreator-created type"
Can this be solved and more important, will it be solved?
Original comment by wd.dewi...@gmail.com
on 18 Jul 2012 at 8:40
The same problem exists with abstract classes (and not only interfaces)
Original comment by ecoffet....@gmail.com
on 24 Aug 2012 at 1:28
You can work around this problem by defining your own TypeAdapter for the
interface type.
Original comment by limpbizkit
on 2 Sep 2012 at 9:43
multiple TypeAdapter cause infinite loop....why it is so??
Original comment by bhavesh4...@gmail.com
on 18 Oct 2012 at 7:29
I have something that you may want to pick up and run with.
im using gwt autobeans and had to figure out a way to make gson work around
incompatible proxies on the server side. what works is to use groovy to be the
enclosing classloader during TypeAdapter registration and for groovy to copmile
the adapter class and register it. the generation code can be cleaned up and
some references to my gson singletions exist here. i think the generated
fromJson method is now superfluous as well. this is the only groovy in my
project, fwiw, using pure java syntax, so cleaner solutions exist with bytecode
engineering, but this one was an easy sample to plug in.
cheers.
import com.google.gson.GsonBuilder;
import com.google.gson.InstanceCreator;
import com.google.gson.internal.bind.ReflectiveTypeAdapterFactory;
import groovy.lang.GroovyClassLoader;
import org.apache.commons.beanutils.PropertyUtils;
import java.beans.PropertyDescriptor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Type;
import java.util.LinkedHashMap;
import java.util.Map;
public class GroovyGsonShimFactory {
private Map<Class, Method> shimMethods = new LinkedHashMap<>();
private void generateGroovyProxy(Class ifaceClass) {
String shimClassName = ifaceClass.getSimpleName() + "$Proxy";
String ifaceClassCanonicalName = ifaceClass.getCanonicalName();
String s = "import com.google.gson.*;\n" +
"import org.apache.commons.beanutils.BeanUtils;\n" +
"import java.lang.reflect.*;\n" +
"import java.util.*;\n\n" +
"public class "+shimClassName+" implements "+ifaceClassCanonicalName+" {\n" ;
{
PropertyDescriptor[] propertyDescriptors = PropertyUtils.getPropertyDescriptors(ifaceClass);
for (PropertyDescriptor p : propertyDescriptors) {
String name = p.getName();
String tname = p.getPropertyType().getCanonicalName();
s += "public " + tname + " " + name + ";\n";
s += " " + p.getReadMethod().toGenericString().replace("abstract", "").replace(ifaceClassCanonicalName + ".", "") + "{return " + name + ";};\n";
Method writeMethod = p.getWriteMethod();
if (writeMethod != null)
s += " " + writeMethod.toGenericString().replace("abstract", "").replace(ifaceClassCanonicalName + ".", "").replace(")", " v){" + name + "=v;};") + "\n\n";
}
}
s+= " public static "+ifaceClassCanonicalName+" fromJson(String s) {\n" +
" return (" +ifaceClassCanonicalName+
")cydesign.strombolian.server.ddl.DefaultDriver.gson().fromJson(s, "+shimClassName+".class);\n" +
" }\n" +
" static public interface foo extends InstanceCreator<"+ifaceClassCanonicalName+">, JsonSerializer<"+ifaceClassCanonicalName+">, JsonDeserializer<"+ifaceClassCanonicalName+"> {}\n" +
" static {\n" +
" cydesign.strombolian.server.ddl.DefaultDriver.builder().registerTypeAdapter("+ifaceClassCanonicalName+".class, new foo() {\n" +
" public "+ifaceClassCanonicalName+" deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {\n" +
" return context.deserialize(json, "+shimClassName+".class);\n" +
" }\n" +
"\n" +
" public "+ifaceClassCanonicalName+" createInstance(java.lang.reflect.Type type) {\n" +
" try {\n" +
" return new "+shimClassName+"();\n" +
" } catch (Exception e) {\n" +
" e.printStackTrace(); \n" +
" }\n" +
" return null;\n" +
" }\n" +
"\n" +
" @Override\n" +
" public JsonElement serialize("+ifaceClassCanonicalName+" src, Type typeOfSrc, JsonSerializationContext context) {\n" +
" LinkedHashMap linkedHashMap = new LinkedHashMap();\n" +
" try {\n" +
" BeanUtils.populate(src, linkedHashMap);\n" +
" return context.serialize(linkedHashMap);\n" +
" } catch (Exception e) {\n" +
" e.printStackTrace(); \n" +
" }\n" +
"\n" +
" return null;\n" +
" }\n" +
" });\n" +
" }\n\n" +
"};";
System.err.println("" + s);
ClassLoader parent = DefaultDriver.class.getClassLoader();
GroovyClassLoader loader = new GroovyClassLoader(parent);
final Class gClass = loader.parseClass(s);
try {
Method shimMethod = gClass.getMethod("fromJson", String.class);
shimMethods.put(ifaceClass, shimMethod);
} catch (NoSuchMethodException e) {
e.printStackTrace();
}
}
public <T> T getShim(String json, Class<T> ifaceClass) {
if (!shimMethods.containsKey(ifaceClass))
generateGroovyProxy(ifaceClass);
T shim = null;//= gson().shimMethods(json, CowSchema.class);
try {
shim = (T) shimMethods.get(ifaceClass).invoke(null, json);
} catch (IllegalAccessException | InvocationTargetException e) {
e.printStackTrace();
}
return shim;
}
}
Original comment by northrup...@gmail.com
on 5 Feb 2014 at 5:31
Is this fixed in any version?
Original comment by mrinmoy....@ideacrestsolutions.com
on 11 Feb 2015 at 4:15
Original issue reported on code.google.com by
jason.po...@gmail.com
on 21 Feb 2012 at 2:33