hacksong / jsonrpc4j

Automatically exported from code.google.com/p/jsonrpc4j
0 stars 0 forks source link

jsonrpc4j does not support named parameters in the json request payload #38

Closed GoogleCodeExporter closed 9 years ago

GoogleCodeExporter commented 9 years ago
According to the JSON-RPC 2.0 specification 
(http://www.jsonrpc.org/specification) two calling modes should be supported; 
'by-position' and 'by-name':

"If present, parameters for the rpc call MUST be provided as a Structured 
value. Either by-position through an Array or by-name through an Object.

by-position: params MUST be an Array, containing the values in the Server 
expected order.
by-name: params MUST be an Object, with member names that match the Server 
expected parameter names. The absence of expected names MAY result in an error 
being generated. The names MUST match exactly, including case, to the method's 
expected parameters."

The specification provides a positional example:

{"jsonrpc": "2.0", "method": "subtract", "params": [42, 23], "id": 1}

And a named example:

{"jsonrpc": "2.0", "method": "subtract", "params": {"subtrahend": 23, 
"minuend": 42}, "id": 3}

The former works in jsonrpc4j, but the later fails with the following error:

{"jsonrpc":"2.0","id":4,"error":{"code":-32602,"message":"Invalid method 
parameters"}}

Original issue reported on code.google.com by brett.wo...@gmail.com on 26 Sep 2012 at 12:51

GoogleCodeExporter commented 9 years ago
This turns out to be an issue with annotations when 
ProxyUtil.createCompositeServiceProxy() is used.  Reflection is performed on 
the handler class, but in this case the handler is a java.lang.Proxy instance, 
and annotations are not available on methods reflected through a Proxy.

Here is a patch that fixes this issue:

Index: src/main/java/com/googlecode/jsonrpc4j/JsonRpcServer.java
===================================================================
--- src/main/java/com/googlecode/jsonrpc4j/JsonRpcServer.java   (revision 238634)
+++ src/main/java/com/googlecode/jsonrpc4j/JsonRpcServer.java   (working copy)
@@ -233,13 +235,18 @@
    }

    /**
-    * Returns the handler's class or interface.
+    * Returns the handler's class or interfaces.
     *
     * @return the class
     */
-   private Class<?> getHandlerClass() {
-       return (remoteInterface != null)
-           ? remoteInterface : handler.getClass();
+   private Class<?>[] getHandlerInterfaces() {
+       if (remoteInterface != null) {
+           return new Class<?>[] {remoteInterface};
+       } else if (Proxy.isProxyClass(handler.getClass())) {
+           return handler.getClass().getInterfaces();
+       } else {
+           return new Class<?>[] {handler.getClass()};
+       }
    }

    /**
@@ -325,7 +332,7 @@

        // find methods
        Set<Method> methods = new HashSet<Method>();
-       methods.addAll(ReflectionUtil.findMethods(getHandlerClass(), methodName));
+       methods.addAll(ReflectionUtil.findMethods(getHandlerInterfaces(), 
methodName));
        if (methods.isEmpty()) {
            writeAndFlushValue(ops, createErrorResponse(
                jsonRpc, id, -32601, "Method not found", null));

Index: src/main/java/com/googlecode/jsonrpc4j/ReflectionUtil.java
===================================================================
--- src/main/java/com/googlecode/jsonrpc4j/ReflectionUtil.java  (revision 238634)
+++ src/main/java/com/googlecode/jsonrpc4j/ReflectionUtil.java  (working copy)
@@ -33,15 +33,21 @@
     * @param name the method name
     * @return the methods
     */
-   public static Set<Method> findMethods(Class<?> clazz, String name) {
-       String cacheKey = clazz.getName().concat("::").concat(name);
+   public static Set<Method> findMethods(Class<?>[] clazzes, String name) {
+       StringBuilder sb = new StringBuilder();
+       for (Class<?> clazz : clazzes) {
+           sb.append(clazz.getName()).append("::");
+       }
+       String cacheKey = sb.append(name).toString();
        if (methodCache.containsKey(cacheKey)) {
            return methodCache.get(cacheKey);
        }
        Set<Method> methods = new HashSet<Method>();
-       for (Method method : clazz.getMethods()) {
-           if (method.getName().equals(name)) {
-               methods.add(method);
+       for (Class<?> clazz : clazzes) {
+           for (Method method : clazz.getMethods()) {
+               if (method.getName().equals(name)) {
+                   methods.add(method);
+               }
            }
        }
        methods = Collections.unmodifiableSet(methods);

Original comment by brett.wo...@gmail.com on 26 Sep 2012 at 3:23

GoogleCodeExporter commented 9 years ago
This patch fixes issue#28, of which this bug appears to be a duplicate.

Original comment by brett.wo...@gmail.com on 26 Sep 2012 at 5:01

GoogleCodeExporter commented 9 years ago
thanks, i plan on resolving this any many other issues in the next day or two.

Original comment by brian.di...@gmail.com on 3 Oct 2012 at 11:22

GoogleCodeExporter commented 9 years ago
patch applied and will be included in next release

Original comment by brian.di...@gmail.com on 5 Oct 2012 at 11:47