Search code examples
javakotlinmailgunlanguage-interoperability

How can I use a Java library that has a .to method in Kotlin as it assumes I mean to use the infix operator for creating a pair


I am using the Mailgun Java API which is used to send emails. There is a .to method on a message builder that you use to populate the recipient's details. However, when I try to use this it tells me that there is a compilation error as it assumes I am trying to use the .to function that creates a pair.

I started with:

Message.builder()
    .from(emailAddress)
    .subject(subject)
    .attachment(File("/path/to/file"))
    .to(recipient)
    .build()

It tells me .build() is an Unresolved Reference and when I hover over .to it shows

public infix fun <A, B> A.to(
    that: B
): Pair<A, B>

as the function it is using. I tried to specify .`to`(recipient) in order to try to get around this and tried to see if I could import the method but this is not possible and I removed this as it tells me

Cannot import 'to', functions and properties can be imported only from packages or objects

I also tried creating an extension function but it can't access the private to property of the MessageBuilder so this doesn't seem possible.


Solution

  • As long as you pass the right type of value for the recipient, the to function from the MessageBuilder will be called instead of the standard library function that creates pairs. Member functions take precedence over extension functions.

    If your code appears to be incorrectly using the standard library to function that builds a Pair, it could mean that your recipient value is the wrong type. When there are multiple functions to choose from, overloads are resolved by looking at the compile-type type of their arguments.

    For example, this doesn't work, because the MessageBuilder.to function doesn't accept an argument of type Any:

    val recipient: Any = "[email protected]"
    Message.builder()
        .to(recipient) // picks the wrong function
        .build()       // doesn't compile
    

    But passing a String allows the compiler to choose the correct function.

    val recipient: String = "[email protected]"
    Message.builder()
        .to(recipient)
        .build()