diff --git a/jsonrpc-java/src/main/java/org/json/rpc/client/JsonRpcInvoker.java b/jsonrpc-java/src/main/java/org/json/rpc/client/JsonRpcInvoker.java index 1ef92d3..e676f03 100644 --- a/jsonrpc-java/src/main/java/org/json/rpc/client/JsonRpcInvoker.java +++ b/jsonrpc-java/src/main/java/org/json/rpc/client/JsonRpcInvoker.java @@ -42,12 +42,23 @@ public final class JsonRpcInvoker { private final TypeChecker typeChecker; + private final Gson gson; + public JsonRpcInvoker() { - this(new GsonTypeChecker()); + this(new GsonTypeChecker(), new Gson()); + } + + public JsonRpcInvoker(Gson gson) { + this(new GsonTypeChecker(), gson); } public JsonRpcInvoker(TypeChecker typeChecker) { + this(typeChecker, new Gson()); + } + + public JsonRpcInvoker(TypeChecker typeChecker, Gson gson) { this.typeChecker = typeChecker; + this.gson = gson; } public T get(final JsonRpcClientTransport transport, final String handle, final Class... classes) { @@ -55,7 +66,6 @@ public T get(final JsonRpcClientTransport transport, final String handle, fi typeChecker.isValidInterface(clazz); } return (T) Proxy.newProxyInstance(JsonRpcInvoker.class.getClassLoader(), classes, new InvocationHandler() { - public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { return JsonRpcInvoker.this.invoke(handle, transport, method, args); } @@ -68,8 +78,6 @@ private Object invoke(String handleName, int id = rand.nextInt(Integer.MAX_VALUE); String methodName = handleName + "." + method.getName(); - Gson gson = new Gson(); - JsonObject req = new JsonObject(); req.addProperty("id", id); req.addProperty("method", methodName); diff --git a/jsonrpc-java/src/main/java/org/json/rpc/commons/GsonTypeChecker.java b/jsonrpc-java/src/main/java/org/json/rpc/commons/GsonTypeChecker.java index 6483a9f..0fcdd91 100644 --- a/jsonrpc-java/src/main/java/org/json/rpc/commons/GsonTypeChecker.java +++ b/jsonrpc-java/src/main/java/org/json/rpc/commons/GsonTypeChecker.java @@ -85,7 +85,7 @@ private boolean isValidType(Class clazz, boolean throwException, Set } boolean zeroArgConstructor = (clazz.getConstructors().length == 0); - for (Constructor c : clazz.getConstructors()) { + for (Constructor c : clazz.getConstructors()) { if (c.getParameterTypes().length == 0) { zeroArgConstructor = true; break; @@ -100,14 +100,12 @@ private boolean isValidType(Class clazz, boolean throwException, Set } // avoid circular references - visited = (visited == null ? new HashSet>() : visited); - if (visited.contains(clazz)) { - if (throwException) { - throw new IllegalArgumentException("circular reference detected : " + clazz); - } + if(visited == null) visited = new HashSet>(); + if (!visited.add(clazz)) { + if (throwException) + throw new IllegalArgumentException("circular reference detected : " + clazz); return false; } - visited.add(clazz); // Check for fields because Gson uses fields for (Field f : clazz.getDeclaredFields()) { @@ -142,6 +140,7 @@ private boolean isValidType(Class clazz, boolean throwException, Set } } + visited.remove(clazz); return true; } diff --git a/jsonrpc-java/src/main/java/org/json/rpc/server/JsonRpcExecutor.java b/jsonrpc-java/src/main/java/org/json/rpc/server/JsonRpcExecutor.java index b1e6725..3f4c51f 100644 --- a/jsonrpc-java/src/main/java/org/json/rpc/server/JsonRpcExecutor.java +++ b/jsonrpc-java/src/main/java/org/json/rpc/server/JsonRpcExecutor.java @@ -56,14 +56,25 @@ public final class JsonRpcExecutor implements RpcIntroSpection { private final TypeChecker typeChecker; private volatile boolean locked; + + private final Gson gson; public JsonRpcExecutor() { - this(new GsonTypeChecker()); + this(new GsonTypeChecker(), new Gson()); + } + + public JsonRpcExecutor(Gson gson) { + this(new GsonTypeChecker(), gson); } - @SuppressWarnings("unchecked") public JsonRpcExecutor(TypeChecker typeChecker) { + this(typeChecker, new Gson()); + } + + @SuppressWarnings("unchecked") + public JsonRpcExecutor(TypeChecker typeChecker, Gson gson) { this.typeChecker = typeChecker; + this.gson = gson; this.handlers = new HashMap>(); addHandler("system", this, RpcIntroSpection.class); } @@ -239,7 +250,7 @@ private JsonElement executeMethod(String methodName, JsonArray params) throws Th Object result = executableMethod.invoke( handleEntry.getHandler(), getParameters(executableMethod, params)); - return new Gson().toJsonTree(result); + return gson.toJsonTree(result); } catch (Throwable t) { if (t instanceof InvocationTargetException) { t = ((InvocationTargetException) t).getTargetException(); @@ -261,7 +272,6 @@ public boolean canExecute(Method method, JsonArray params) { public Object[] getParameters(Method method, JsonArray params) { List list = new ArrayList(); - Gson gson = new Gson(); Class[] types = method.getParameterTypes(); for (int i = 0; i < types.length; i++) { JsonElement p = params.get(i);