We have been using the apache commons pool to hold our Avro proxy objects, and 
we recently upgraded to commons-pool2.  This exposed an issue with 
SpecificRequestor.

In a nutshell, commons-pool2's GenericKeyedObjectPool.create() attempts to put 
pool object wrappers into a map, keying off the original object:

objectDeque.getAllObjects().put(p.getObject(), p);

The put() calls hashCode() which is not handled in the invoke method of 
SpecificRequestor.  For a quick workaround, I extended SpecificRequestor and 
checked for hashCode, equals and toString.  But this could easily be applied 
directly to SpecificRequestor.  Most of this is taken from the Java source in 
RemoteObjectInvocationHandler, with a small change in toString() to display the 
Avro proxy url if available:


    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws 
Throwable {
        String name = method.getName();
        if (name.equals("hashCode")) {
            return hashCode();
        } else if (name.equals("equals")) {
            Object obj = args[0];
            return proxy == obj || (obj != null && 
Proxy.isProxyClass(obj.getClass()) && equals(Proxy.getInvocationHandler(obj)));
        } else if (name.equals("toString")) {
            return proxyToString(proxy);
        } else {
            return super.invoke(proxy, method, args);
        }
    }

    private String proxyToString(Object proxy) {
        Class<?>[] interfaces = proxy.getClass().getInterfaces();
        if (interfaces.length == 0) {
            return "Proxy[" + this + "]";
        }
        String iface = interfaces[0].getName();
        if (iface.equals("java.rmi.Remote") && interfaces.length > 1) {
            iface = interfaces[1].getName();
        }
        int dot = iface.lastIndexOf('.');
        if (dot >= 0) {
            iface = iface.substring(dot + 1);
        }

        try {
            InvocationHandler handler = Proxy.getInvocationHandler(proxy);
            if (handler instanceof Requestor) {
                String url = ((Requestor) 
handler).getTransceiver().getRemoteName();
                return "Proxy[" + iface + "," + url + "]";
            }
        } catch (IOException e) {
        }
        return "Proxy[" + iface + "," + this + "]";
    }


Apologies if this has already been discussed: the archives search did not 
appear to be working.  Thanks,

Mark


Reply via email to