vendredi 27 octobre 2017

How to invoke with reflection a Java function which has method reference as parameters

A class (from Elasticsearch Rest API) has a protected method that I want to invoke. The problem is that this method has method reference parameters :

protected <Req extends ActionRequest, Resp> Resp performRequestAndParseEntity(
            Req request,
            CheckedFunction<Req, Request, IOException> requestConverter,
            CheckedFunction<XContentParser, Resp, IOException> entityParser,
            Set<Integer> ignores, Header... headers) throws IOException {
    return performRequest(request, requestConverter, (response) ->
        parseEntity(response.getEntity(), entityParser), ignores, headers);
}

In the API, this method is called that way:

DeleteIndexResponse deleteIndexResponse = restHighLevelClient.performRequestAndParseEntity(
    deleteIndexRequest,
    Request::deleteIndex,
    DeleteIndexResponse::fromXContent,
    Collections.emptySet(),
    headers
);

Java tells me that "The target type of this expression must be a functional interface" for DeleteIndexRequest::deleteIndex and DeleteIndexResponse::fromXContent

My (not working) solution:

java.lang.Class clazz = restHighLevelClient.getClass();
java.lang.reflect.Method performRequestAndParseEntity = clazz.getDeclaredMethod(
    "performRequestAndParseEntity",
    Object.class,
    org.elasticsearch.common.CheckedFunction.class,
    org.elasticsearch.common.CheckedFunction.class,
    java.util.Set.class,
    org.apache.http.Header.class
);
performRequestAndParseEntity.setAccessible(true);

org.elasticsearch.action.admin.indices.delete.DeleteIndexResponse 
deleteIndexResponse = (org.elasticsearch.action.admin.indices.delete.DeleteIndexResponse)
    performRequestAndParseEntity.invoke(
        restHighLevelClient,
        deleteByIndexRequest,
        org.elasticsearch.action.admin.indices.delete.DeleteIndexRequest::deleteIndex,
        org.elasticsearch.action.admin.indices.delete.DeleteIndexResponse::fromXContent,
        java.util.Collections.emptySet(),
        null
    )
;





Aucun commentaire:

Enregistrer un commentaire