diff -ur jna-3.0.4-svn630/src/com/sun/jna/CallbackReference.java jna-3.0.4-svn630.orig/src/com/sun/jna/CallbackReference.java --- jna-3.0.4-svn630/src/com/sun/jna/CallbackReference.java 2008-07-31 13:44:21.000000000 -0400 +++ jna-3.0.4-svn630.orig/src/com/sun/jna/CallbackReference.java 2008-09-03 09:04:35.000000000 -0400 @@ -16,6 +16,7 @@ import java.lang.reflect.InvocationHandler; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; +import java.lang.reflect.Field; import java.lang.reflect.Proxy; import java.util.HashMap; import java.util.Iterator; @@ -150,22 +151,45 @@ } return cls; } + + private static Method checkMethod(Method m) { + if (m.getParameterTypes().length > Function.MAX_NARGS) { + String msg = "Method signature exceeds the maximum " + + "parameter count: " + m; + throw new IllegalArgumentException(msg); + } + return m; + } private static Method getCallbackMethod(Callback callback) { - Method[] mlist = callback.getClass().getMethods(); + Class klass = callback.getClass(); + Method[] mlist = klass.getDeclaredMethods(); + + /* If there's only one method, just try it. */ + if (mlist.length == 1) + return checkMethod(mlist[0]); + + /* Now try looking for a field named "METHOD_NAME" which + * tells us which method to use. + */ + String methName = Callback.METHOD_NAME; + try { + Field methNameField = klass.getField("METHOD_NAME"); + methName = (String) methNameField.get(null); + } catch (NoSuchFieldException e) { + } catch (Exception e) { + String msg = "Callback METHOD_NAME field is invalid"; + throw new IllegalArgumentException(msg); + } + for (int mi=0;mi < mlist.length;mi++) { Method m = mlist[mi]; - if (Callback.METHOD_NAME.equals(m.getName())) { - if (m.getParameterTypes().length > Function.MAX_NARGS) { - String msg = "Method signature exceeds the maximum " - + "parameter count: " + m; - throw new IllegalArgumentException(msg); - } - return m; + if (methName.equals(m.getName())) { + return checkMethod(m); } } String msg = "Callback must implement method named '" - + Callback.METHOD_NAME + "'"; + + methName + "'"; throw new IllegalArgumentException(msg); }