Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Changed method typecheck algorithm for non-builtins so that it

considers each class and interface in the class hierarchy as a
candidate for a matching method. Previously only class methods were
considered which meant that a call to an (undefined) interface method
of an abstract class was failing with a method not found error even
though there is guaranteed to be an actual implementation of that
method at runtime. fixes BYTEMAN-219
  • Loading branch information...
commit d0757771ba90a3cafb7d69b6de5d132e4d310673 1 parent 473119c
@adinn adinn authored
View
43 agent/src/main/java/org/jboss/byteman/rule/expression/MethodExpression.java
@@ -36,6 +36,7 @@
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;
+import java.util.LinkedList;
import java.util.List;
import java.util.Iterator;
import java.util.ArrayList;
@@ -205,9 +206,41 @@ private void findMethod(boolean publicOnly) throws TypeException
boolean isStatic = (recipient == null);
int arity = arguments.size();
- while (clazz != null) {
+ LinkedList<Class<?>> clazzes = new LinkedList<Class<?>>();
+ if (publicOnly) {
+ // we can use getDeclaredMethods on just one class to list all possible candidates
+ clazzes.add(clazz);
+ } else {
+ // we need to iterate over the class and interface hierarchy bottom up
+ while (clazz != null) {
+ clazzes.add(clazz);
+ // collect all direct interfaces in order
+ Class[] ifaces = clazz.getInterfaces();
+ LinkedList<Class<?>> toBeChecked = new LinkedList<Class<?>>();
+ for (int i = 0; i < ifaces.length; i++) {
+ toBeChecked.addLast(ifaces[i]);
+ }
+ // process each interface in turn, also collecting its parent interfaces for consideration
+ while (!toBeChecked.isEmpty()) {
+ Class<?> iface = toBeChecked.pop();
+ // only need to process it if we have not already seen it
+ if (!clazzes.contains(iface)) {
+ clazzes.addLast(iface);
+ Class[] ifaces2 = iface.getInterfaces();
+ // don't bother to check for repeats here as we check later anyway
+ for (int j = 0; j < ifaces2.length; j++) {
+ toBeChecked.addLast(ifaces2[j]);
+ }
+ }
+ }
+ // move on to the next class
+ clazz = clazz.getSuperclass();
+ }
+ }
+ // now check for a matching method in each class or interface in order
+ while (!clazzes.isEmpty()) {
+ clazz = clazzes.pop();
List<Method> candidates = new ArrayList<Method>();
- Class<?> superClazz = clazz.getSuperclass();
try {
Method[] methods;
if (publicOnly) {
@@ -280,12 +313,6 @@ private void findMethod(boolean publicOnly) throws TypeException
} catch (SecurityException e) {
// continue in case we can find an implementation
}
-
- if (publicOnly) {
- clazz = null;
- } else {
- clazz = superClazz;
- }
}
// no more possible candidates so throw up here
Please sign in to comment.
Something went wrong with that request. Please try again.