2

I need to use reflection with generic params. Here is an example class and test class of what I am trying to do. Running the test, I am getting error:

[ERROR : Method not found exception] : Method name 'EST2GMT'

Here is my reflect class with generic;

/*
 * File: MyTransformer.java
 * Created: Jul 22, 2014
*/

package company.online.project.my.transform;

import java.lang.reflect.Method;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.List;
import org.apache.log4j.Logger;

public class MyTransformer< T >
{

Logger LOG = Logger.getLogger( MyTransformer.class );

public T tranform( String functionName, T arg )
{

    try
    {
        Method method = this.getClass().getDeclaredMethod( functionName, arg.getClass() );
        return (T) method.invoke( this, arg );
    }
    catch ( NoSuchMethodException e )
    {
        System.out.println( "[ERROR : Method not found exception] : Method name '" + functionName + "'" );
    }
    catch ( java.lang.IllegalAccessException e )
    {
        System.out.println( "[ERROR : Illegal Access exception] : " + e.getMessage() );
    }
    catch ( java.lang.reflect.InvocationTargetException e )
    {
        System.out.println( "[ERROR : Invocation Target not found exception] : " + e.getMessage() );
    }
    return null;
}

public Date convert2Date( String date )
{
    LOG.debug( "convert2Date function called" );
    return new Date();
}

public Calendar EST2GMT( Calendar estTime )
{
    LOG.debug( "EST2GMT function called :" + estTime.getTime().toString() );
    return new GregorianCalendar( 2013, 0, 31 );
}

public String createcompanyKeys( List<T> values )
{
    LOG.debug( "EST2GMT function called" );
    return "String";
}

}

Here is my test class :

package company.online.project.my.transform;

import java.lang.reflect.InvocationTargetException;
import java.util.Calendar;
import java.util.GregorianCalendar;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;

public class MyTransformerTest
{

MyTransformer transformer;

@Before
public void setUp()
{
    transformer = new MyTransformer();
}

@Test
public void testGetMethod() throws SecurityException, NoSuchMethodException, IllegalArgumentException,
        IllegalAccessException, InvocationTargetException
{
    Calendar calendar = new GregorianCalendar( 2013, 0, 31 );
    Assert.assertEquals( Calendar.class, transformer.tranform( "EST2GMT", calendar.getClass() );
}

}

1 Answer 1

4

You are passing a GregorianCalendar to a method that takes a Calendar. But with reflection, you didn't find any method that takes a GregorianCalendar, even though it's legal in normal Java method invocation to pass an instance of a subclass of the parameter's type to a method.

To find the method that takes a Calendar, then if you don't find a method with the exact Class match, catch the NoSuchMethodException and try again with the class's superclass, which you can get from the Class object with the getSuperclass() method, until you have failed to find the method even with Object.

Also, you are passing a Class object as the actual parameter to the method to be invoked using reflection.

transformer.tranform( "EST2GMT", calendar.getClass())

Pass the actual object instead. Also, call .getClass() after the ()s to get the class of the returned object.

transformer.tranform( "EST2GMT", calendar).getClass()

The test case will still fail, because the actual type of what's returned is GregorianCalendar, which is not the same class Calendar. This will pass:

Assert.assertEquals( GregorianCalendar.class,
    transformer.tranform( "EST2GMT", calendar ).getClass() );

If you just want to know if it's any kind of Calendar, an instanceof will suffice:

Assert.assertTrue(transformer.tranform("EST2GMT", calendar) instanceof Calendar);
Sign up to request clarification or add additional context in comments.

3 Comments

Even if you are searching with getSuperClass(), your test will fail because it expects a Calendar but gets a GregorianCalendar again.
tried with .getClass().getSuperClass() and still getting that error. Also tried with thid modified part in the testGetMethod(). Did not work either. Getting the same error
I've added more explanation about what went wrong with the test.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.