Calling a java method that expect Class<T>?


#1

I am trying to call a java method from the Apache Camel ProducerTemplate, the method is declared in java as:

<T> T requestBodyAndHeaders(String endpointUri, Object body, Map<String, Object> headers, Class<T> type) throws CamelExecutionException;

I my case the Class is List<Data.Offer> when I use the following Kotlin code:

producerTemplate.requestBodyAndHeaders(endpoint, null, params, MutableList<Data.Offer>::class.java)

It does not compile, I end up using the following, bur the compile is giving type casts warnings.

abstract class CamelBaseSupplier(val camelContext: CamelContext) : Supplier {
    open fun requestOffers(endpoint: String, params: Map<String, Any>): MutableList<*> {
        val producerTemplate = camelContext.createProducerTemplate()
        return producerTemplate.requestBodyAndHeaders(endpoint, null, params, MutableList::class.java)
    }
}

Thank you.


#2

Replace that with this and it compiles without warning for me:

producerTemplate.requestBodyAndHeaders(endpoint, null, params, MutableList::class.java)

#3

Hi @dalewking:

yeap, this is what I used but the compilation working happens when I try to use this method in from a child inheritant class
the consumer code looks like:

val offers = requestOffers(ENDPOINT, params) as MutableList<Data.Offer> 

At this point I do need the type of the list to containt Data.Offer objects so I had to use the cast.
So my question is how to I declared that I expect the result of the call to result object of the type MutableList<Data.Offer> ?

Thank you, kindly


#4

Afraid you’re running into the limitation of the JVM type system and the way that generics are implemented on the JVM and not a problem with Kotlin. You would have the exact same problem on plain Java. A class object knows absolutely nothing about any generic parameters.

It appears in this case what you want is to do the cast inside of requestOffers and suppress the unchecked cast:

abstract class CamelBaseSupplier(val camelContext: CamelContext) : Supplier {
    @Suppress("UNCHECKED_CAST")
    open fun requestOffers(endpoint: String, params: Map<String, Any>)
        = camelContext.createProducerTemplate()
             .requestBodyAndHeaders(endpoint, null, params, MutableList::class.java)
              as MutableList<Data.Offer>
}

Even if you were doing this in Java you would also have an unchecked cast due to Java’s use of type erasure for generics


#5

Thank you for the great insight.:slight_smile: