0

How with reflection do I pass a method parameter com.ibm.as400.access.AS400JDBCConnection to the following method:

    private String test1(Connection con){

    return "test1";
}

When I pass from my JUnit to the test1(con) I get the following error. java.lang.NoSuchMethodException: com.action.TestAction.test1(com.ibm.as400.access.AS400JDBCConnection)

I created another method:

    private String test2(com.ibm.as400.access.AS400JDBCConnection con){

    return "test2";
}

Run with test2(con) and it runs fine. Any input would be greatly appreciated on proper passing into test1 without alteration to the method.

==========================================================

The following is the example link I pulled from: Any way to Invoke a private method?

The following is my JUnit test:

@Test
public void testReturnScreen(){


    System.out.println("connection: "+con.getClass());
    System.out.println((String) genericInvokMethod(creditCardAction, "test2", 1, con));
    System.out.println((String) genericInvokMethod(creditCardAction, "test1", 1, con));

}

public static Object genericInvokMethod(Object obj, String methodName,
        int paramCount, Object... params) {
    Method method;
    Object requiredObj = null;
    Object[] parameters = new Object[paramCount];
    Class<?>[] classArray = new Class<?>[paramCount];
    for (int i = 0; i < paramCount; i++) {
        parameters[i] = params[i];
        classArray[i] = params[i].getClass();
    }
    try {
        method = obj.getClass().getDeclaredMethod(methodName, classArray);
        method.setAccessible(true);
        requiredObj = method.invoke(obj, parameters);
    } catch (NoSuchMethodException e) {
        e.printStackTrace();
    } catch (IllegalArgumentException e) {
        e.printStackTrace();
    } catch (IllegalAccessException e) {
        e.printStackTrace();
    } catch (InvocationTargetException e) {
        e.printStackTrace();
    }

    return requiredObj;
}
Community
  • 1
  • 1
ogottwald
  • 113
  • 1
  • 3
  • 15

1 Answers1

0

If con is of type AS400JDBCConnection, then getDeclaredMethod(methodName, classArray) will find nothing since your test1 method is defined with a Connection formal parameter, so it will throw the exception.

I think you could alter your genericInvokeMethod to something like:

public static Object genericInvokMethod(Object obj, String methodName, Object[] formalParams, Object[] actualParams) {
    Method method;
    Object requiredObj = null;

    try {
        method = obj.getClass().getDeclaredMethod(methodName, formalParams);
        method.setAccessible(true);
        requiredObj = method.invoke(obj, actualParams);
    } catch (NoSuchMethodException e) {
        e.printStackTrace();
    } catch (IllegalArgumentException e) {
        e.printStackTrace();
    } catch (IllegalAccessException e) {
        e.printStackTrace();
    } catch (InvocationTargetException e) {
        e.printStackTrace();
    }

    return requiredObj;
}

... and invoke it like:

System.out.println((String) genericInvokMethod(creditCardAction, "test1", new Object[]{Connection.class}, new Object[]{con}));

I haven't tested whether the code compiles, but you get the idea.

Morfic
  • 15,178
  • 3
  • 51
  • 61
  • Also if you could provide more info on what you're trying to achieve, perhaps we could bypass reflection and come up with a more elegant solution. – Morfic Oct 18 '13 at 21:13
  • That worked! Thank you - I'm calling a private method in a Struts Action passing a number of parameters. I don't want to duplicate the code and I don't want to change the Action. Also using EasyMock and getting an issue on class $Proxy5 from are above example but that is another POST I think. – ogottwald Oct 18 '13 at 22:41