The Class.isAssignableFrom(Class) call in line 65 is backwards.
We have an agent that instruments classes that implement java.sql.Connection. It adds a getter method that returns java.lang.Object. With the agent injected, since the isAssignableCheck is backwards, a ClassCastException is thrown.
The fix is easy:
(java.sql.Connection.class.isAssignableFrom(method.getReturnType()))
I believe this was the orignal intention, like:
(methodReturnValue instanceof java.sql.Connection)
Class.isAssignableFrom must always be called reverse to it's "instanceof" counterpart.
I'm appending a small demo program to reproduce the issue.
package foo;
public class Foo {
interface Connection {
String getName();
}
interface I1 {
Connection getConnection();
Object getConnectionData();
}
static class Impl1 implements I1 {
@Override
public Connection getConnection() {
return new Connection() {
@Override
public String getName() {
return "ValidConnection";
}
};
}
@Override
public Object getConnectionData() {
return "CData";
}
}
public static void main(String[] args) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException {
foo(new Impl1());
}
private static void foo(Impl1 o) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException {
for (Method method : o.getClass().getMethods()) {
// if (Connection.class.isAssignableFrom(method.getReturnType())) { // CORRECT
if (method.getReturnType().isAssignableFrom(Connection.class)) { // WRONG
Connection c = (Connection) method.invoke(o);
System.out.println(c.getName());
} else {
System.out.println("Skip: "+method);
}
}
}
}
The Class.isAssignableFrom(Class) call in line 65 is backwards. We have an agent that instruments classes that implement java.sql.Connection. It adds a getter method that returns java.lang.Object. With the agent injected, since the isAssignableCheck is backwards, a ClassCastException is thrown. The fix is easy: (java.sql.Connection.class.isAssignableFrom(method.getReturnType())) I believe this was the orignal intention, like: (methodReturnValue instanceof java.sql.Connection) Class.isAssignableFrom must always be called reverse to it's "instanceof" counterpart.
I'm appending a small demo program to reproduce the issue.