1 Reply Latest reply on Jan 20, 2011 2:52 PM by jgarrison

    Problem with equals/hashCode?

    jgarrison

      When MethodHandler.invoke() is called by Javassist for invocations of equals() and hashCode(), the "proceed" method object is not named "equals" or "hashCode", but is instead something like _d2hashCode.  This is different from normal method invocation where the proceed method is the superclass implementation.  Why does the generated proxy provide an implementation of these two methods?

       

      We're trying to implement a proxy wrapper for an object that implements its own hashCode and equals, and would like to detect this situation so as to delegate to the wrapped object's equals() and hashCode().  Since the method name is mangled, what can we rely on to detect this situation unequivocally?  What I've come up with is the following, to determine the actual implementation class for equals() and hashCode().

       

              private Class<?> getRealDeclaringClass(Method m) throws NoSuchMethodException

              {

                  Class<?> dcl = m.getDeclaringClass();

                  String name = m.getName().contains("equals") ? "equals" : m.getName().contains("hashCode") ? "hashCode" : null;

                  if (name != null)

                  {

                      Method impl = m.getDeclaringClass().getSuperclass().getMethod(name,m.getParameterTypes());

                      dcl = impl.getDeclaringClass();

                  }

                  return dcl;

              }

       

      Is this correct?

        • 1. Problem with equals/hashCode?
          jgarrison

          Better implementation of getRealDeclaringClass()

           

                  private Class<?> getRealDeclaringClass(Method m) throws NoSuchMethodException

                  {

                      // Get the method's current declaring class

                      Class<?> dcl = m.getDeclaringClass();

                      // Special handling for equals and hashCode() -- first unmangle the name

                      String name = m.getName().contains("equals") ? "equals" : m.getName().contains("hashCode") ? "hashCode" : null;

                      if (name != null)

                      {

                          // Walk up the class hierarchy to the first non-proxy class

                          while(dcl.getName().contains("javassist"))

                              dcl = dcl.getSuperclass();

                          // Now get the declaring class of the unmangled name

                          dcl = dcl.getMethod(name,m.getParameterTypes()).getDeclaringClass();

                      }

                      return dcl;

                  }