Thanks, I've removed this restriction in master already. One correction, the assumption about Command class and all of its inherited classes are required to locate in the same java package. It looks like that even if the constraint is fulfilled from code logic, the timing of initializing static variable s_pkg is causing the problem I had. It caused json desserializer failed to do its job.
For good and bad, you may put Command inherited classes in any other java package now in master branch. Kelven On 7/15/13 12:06 PM, "Min Chen" <min.c...@citrix.com> wrote: >In 4.2 during object_store refactoring, we have removed that assumption. > >Thanks >-min > >On 7/8/13 7:44 PM, "Kelven Yang" <kelven.y...@citrix.com> wrote: > >>When I ran a build from latest 4.1 branch, I found an issue and I'm >>wondering why it is not breaking 4.1.1 builds from others, here is some >>of details >> >> >>public class ArrayTypeAdaptor<T> implements JsonDeserializer<T[]>, >>JsonSerializer<T[]> { >> >> >> protected Gson _gson = null; >> >> >> >> private static final String s_pkg = >>Command.class.getPackage().getName() + "."; >> >> >> public ArrayTypeAdaptor() { >> >> } >> >> >> public void initGson(Gson gson) { >> >> _gson = gson; >> >> } >> >> >> @Override >> >> public JsonElement serialize(T[] src, Type typeOfSrc, >>JsonSerializationContext context) { >> >> JsonArray array = new JsonArray(); >> >> for (T cmd : src) { >> >> JsonObject obj = new JsonObject(); >> >> obj.add(cmd.getClass().getName().substring(s_pkg.length()), >>_gson.toJsonTree(cmd)); >> >> array.add(obj); >> >> } >> >> >> return array; >> >> } >> >> >> @Override >> >> @SuppressWarnings("unchecked") >> >> public T[] deserialize(JsonElement json, Type typeOfT, >>JsonDeserializationContext context) >> >> throws JsonParseException { >> >> JsonArray array = json.getAsJsonArray(); >> >> Iterator<JsonElement> it = array.iterator(); >> >> ArrayList<T> cmds = new ArrayList<T>(); >> >> while (it.hasNext()) { >> >> JsonObject element = (JsonObject)it.next(); >> >> Map.Entry<String, JsonElement> entry = >>element.entrySet().iterator().next(); >> >> >> String name = s_pkg + entry.getKey(); >> >> Class<?> clazz; >> >> try { >> >> clazz = Class.forName(name); >> >> } catch (ClassNotFoundException e) { >> >> throw new CloudRuntimeException("can't find " + name); >> >> } >> >> T cmd = (T)_gson.fromJson(entry.getValue(), clazz); >> >> cmds.add(cmd); >> >> } >> >> Class<?> type = ((Class<?>)typeOfT).getComponentType(); >> >> T[] ts = (T[])Array.newInstance(type, cmds.size()); >> >> return cmds.toArray(ts); >> >> } >> >>} >> >> >>Inside ArrayTypeAdapter, it retrieves the package info from where >>ArrayTypeAdaatper.class locates at run time. and it assumes that all >>array element object classes are also from the same java package (up to >>the package detail path above the class name). Apparently we have >>relocated many of classes, for example, ArrayTypeAdatper is currently at >>com.cloud.agent.transport and agent cmd classes are mostly put under >>com.cloud.agent.api now. >> >> >>I'm going to remove this hard-coded assumption about the package location >>of ArrayTypeAdatper class and related agent command classes. Anyone has a >>different idea? >> >> >>Kelven >> >> >