Mopparthy Ravindranath
Mopparthy Ravindranath

Reputation: 3318

Java generics NoSuchMethodError

I am trying to create a generic MsgRequest Class that can set/get any type of parameter. The intention here is to create a lightweight container for various types of parameters in a Message and pass it to various method calls.

public class MsgRequest {

//private HashMap<String, String> _params = new HashMap<>();
private final HashMap<String, Object> _params = new HashMap<>();

/**
 * Returns the value of a specified key, if found, null otherwise.
 * @param key
 * @return 
 */

public <T> T getX(String key) {
    return (T) _params.get(key);
}


/**
 * Sets / replaces a given key in Message params.
 * @param <T>
 * @param key 
 */
public <T> void setX(String key, T element) {
    //TODO: Implement 2nd param as a generic type.
    //_params.put(key, element);
}

When I try to test this class like below,

@Test
public void testGetString() {
    MsgRequest msg = new MsgRequest();
    String key = "one";
    String val = "This is one.";
    msg.setX(key, val);
    //String s = msg.getX("one");
    assertTrue("result should be string type", msg.getX("one") instanceof String);
}

Then it throws java.lang.NoSuchMethodError.

Testcase: testGetString(com.msgx.MsgRequest.MsgRequestTest): Caused an ERROR com.msgx.MsgRequest.MsgRequest.setX(Ljava/lang/String;Ljava/lang/Object;)V java.lang.NoSuchMethodError: com.msgx.MsgRequest.MsgRequest.setX(Ljava/lang/String;Ljava/lang/Object;)V at com.msgx.MsgRequest.MsgRequestTest.testGetString(MsgRequestTest.java:48)

Unable to figure out how to fix this exception. Any suggestions?

Upvotes: 4

Views: 1466

Answers (1)

Elliott Frisch
Elliott Frisch

Reputation: 201507

Make the class MsgRequest generic like

public class MsgRequest<T> {
    private final Map<String, T> _params = new HashMap<>();

    /**
     * Returns the value of a specified key, if found, null otherwise.
     * @param key
     * @return 
     */
    public T getX(String key) {
        return _params.get(key);
    }

    /**
     * Sets / replaces a given key in Message params.
     * @param <T>
     * @param key 
     */
    public void setX(String key, T element) {
        _params.put(key, element);
    }
}

And then use it like

@Test
public void testGetString() {
    MsgRequest<String> msg = new MsgRequest<>();
    String key = "one";
    String val = "This is one.";
    msg.setX(key, val);
    assertTrue("result should be string type", 
        msg.getX("one") instanceof String);
}

Upvotes: 2

Related Questions