[jboss-dev-forums] [Design of AOP on JBoss (Aspects/JBoss)] - Re: Creation of method tables in ClassAdvisor

flavia.rainone@jboss.com do-not-reply at jboss.com
Wed May 13 10:51:51 EDT 2009


Jaikiran wrote : 2) The MethodHashing.methodHash() does some very specific/involved logic. How is it different from a normal method.hashCode()?

Taking a look at the J2SE API (http://java.sun.com/javase/6/docs/api/):

anonymous wrote : public int hashCode()
  | 
  |     Returns a hashcode for this Method. The hashcode is computed as the exclusive-or of the hashcodes for the underlying method's declaring class name and the method's name.
  | 
  | 

And at the MethodHashing.methodHash(Method) implementation:

public static long methodHash(Method method)
  |       throws Exception
  |    {
  |       Class<?>[] parameterTypes = method.getParameterTypes();
  |       StringBuffer methodDesc = new StringBuffer(method.getName()+"(");
  |       for(int j = 0; j < parameterTypes.length; j++)
  |       {
  |          methodDesc.append(getTypeString(parameterTypes[j]));
  |       }
  |       methodDesc.append(")"+getTypeString(method.getReturnType()));
  |       return createHash(methodDesc.toString());
  |    }

We can see that the Sun's version takes into account the name of the class and the name of the method, whilest the JBoss AOP implementation takes into account the name of the method, the types of the parameters and the reutrn type of the method. This is because we need an unique hash code per method:
long hash = MethodHashing.methodHash(declaredMethods);
  |             advisedMethods.put(hash, declaredMethods);

The complicated bits are in the createHash method:

public static long createHash(String methodDesc)
  |    	throws Exception
  |    {
  |       long hash = 0;
  |       ByteArrayOutputStream bytearrayoutputstream = new ByteArrayOutputStream(512);
  |       MessageDigest messagedigest = MessageDigest.getInstance("SHA");
  |       DataOutputStream dataoutputstream = new DataOutputStream(new DigestOutputStream(bytearrayoutputstream, messagedigest));
  |       dataoutputstream.writeUTF(methodDesc);
  |       dataoutputstream.flush();
  |       byte abyte0[] = messagedigest.digest();
  |       for(int j = 0; j < Math.min(8, abyte0.length); j++)
  |          hash += (long)(abyte0[j] & 0xff) << j * 8;
  |       return hash;
  |       
  |    }

This method processes the string with a Message Digester, using the SHA algorithm, generating an unique byte array for each string. Then, the resulting array is transformed in a single byte by concatenating each first 8 bits of the first 8 bytes in the array. The result should be an unique hash code for each method. I'm not sure about this, since we are disposing of part of the resulting byte array, and using only the first 8 bits of the first 8 bytes (I guess I would have to ask to Mark Fleury, the author of this class). But I think that, if the hash code weren't unique, we would see failures at the JBoss AOP testsuite.

So, the short answer is that: Method.hasCode() is going to generate the same code for overloaded methods, but we need a hash code that is unique per method.

View the original post : http://www.jboss.org/index.html?module=bb&op=viewtopic&p=4230869#4230869

Reply to the post : http://www.jboss.org/index.html?module=bb&op=posting&mode=reply&p=4230869



More information about the jboss-dev-forums mailing list