@@ -153,11 +153,11 @@ else if(methods.size() == 1)
153153 if (m == null )
154154 throw new IllegalArgumentException (noMethodReport (methodName ,target ,args ));
155155
156- if (!Modifier .isPublic (m .getDeclaringClass ().getModifiers ()))
156+ if (!Modifier .isPublic (m .getDeclaringClass ().getModifiers ()) || ! canAccess ( m , target ) )
157157 {
158158 //public method of non-public class, try to find it in hierarchy
159159 Method oldm = m ;
160- m = getAsMethodOfPublicBase (target .getClass (), m );
160+ m = getAsMethodOfAccessibleBase (target .getClass (), m , target );
161161 if (m == null )
162162 throw new IllegalArgumentException ("Can't call public method of non-public class: " +
163163 oldm .toString ());
@@ -173,6 +173,7 @@ else if(methods.size() == 1)
173173
174174}
175175
176+ // DEPRECATED - replaced by getAsMethodOfAccessibleBase()
176177public static Method getAsMethodOfPublicBase (Class c , Method m ){
177178 for (Class iface : c .getInterfaces ())
178179 {
@@ -197,6 +198,7 @@ public static Method getAsMethodOfPublicBase(Class c, Method m){
197198 return getAsMethodOfPublicBase (sc , m );
198199}
199200
201+ // DEPRECATED - replaced by isAccessibleMatch()
200202public static boolean isMatch (Method lhs , Method rhs ) {
201203 if (!lhs .getName ().equals (rhs .getName ())
202204 || !Modifier .isPublic (lhs .getDeclaringClass ().getModifiers ()))
@@ -221,6 +223,55 @@ public static boolean isMatch(Method lhs, Method rhs) {
221223 return match ;
222224}
223225
226+ public static Method getAsMethodOfAccessibleBase (Class c , Method m , Object target ){
227+ for (Class iface : c .getInterfaces ())
228+ {
229+ for (Method im : iface .getMethods ())
230+ {
231+ if (isAccessibleMatch (im , m , target ))
232+ {
233+ return im ;
234+ }
235+ }
236+ }
237+ Class sc = c .getSuperclass ();
238+ if (sc == null )
239+ return null ;
240+ for (Method scm : sc .getMethods ())
241+ {
242+ if (isAccessibleMatch (scm , m , target ))
243+ {
244+ return scm ;
245+ }
246+ }
247+ return getAsMethodOfAccessibleBase (sc , m , target );
248+ }
249+
250+ public static boolean isAccessibleMatch (Method lhs , Method rhs , Object target ) {
251+ if (!lhs .getName ().equals (rhs .getName ())
252+ || !Modifier .isPublic (lhs .getDeclaringClass ().getModifiers ())
253+ || !canAccess (lhs , target ))
254+ {
255+ return false ;
256+ }
257+
258+ Class [] types1 = lhs .getParameterTypes ();
259+ Class [] types2 = rhs .getParameterTypes ();
260+ if (types1 .length != types2 .length )
261+ return false ;
262+
263+ boolean match = true ;
264+ for (int i =0 ; i <types1 .length ; ++i )
265+ {
266+ if (!types1 [i ].isAssignableFrom (types2 [i ]))
267+ {
268+ match = false ;
269+ break ;
270+ }
271+ }
272+ return match ;
273+ }
274+
224275public static Object invokeConstructor (Class c , Object [] args ) {
225276 try
226277 {
0 commit comments