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
>>
>>
>

Reply via email to