Search code examples
javakotlinexceptiontry-with-resourcesresource-management

Is there way to have multi resource "try with resources" in Kotlin?


I have java function(taken from here):

/**
 * Checks to see if a specific port is available.
 *
 * @param port the port to check for availability
 */
public static boolean available(int port) {
    if (port < MIN_PORT_NUMBER || port > MAX_PORT_NUMBER) {
        throw new IllegalArgumentException("Invalid start port: " + port);
    }

    ServerSocket ss = null;
    DatagramSocket ds = null;
    try {
        ss = new ServerSocket(port);
        ss.setReuseAddress(true);
        ds = new DatagramSocket(port);
        ds.setReuseAddress(true);
        return true;
    } catch (IOException e) {
    } finally {
        if (ds != null) {
            ds.close();
        }

        if (ss != null) {
            try {
                ss.close();
            } catch (IOException e) {
                /* should not be thrown */
            }
        }
    }

    return false;
}

I want to rewrite it in Kotlin without ugly constructions.

So I've found this topic:

Try-with-resources in Kotlin

As far I understood I have to create object first and inside of use lambda I have to to call method which could throw Exception but in case of

ServerSocket(port)
DatagramSocket(port)

Exception will be thrown in constructor. So looks like it doesn't fit my needs.

So how can I rewrite this code in Kotlin ?


Solution

  • If the exception is thrown in the constructor, you will have no reference to close... I think this could be written in idiomatic kotlin like this:

    return runCatching {
        ServerSocket(port).use { ss ->
            ss.reuseAddress = true
            DatagramSocket(port).use { ds ->
                ds.reuseAddress = true
            }
        }
    }.isSuccess
    

    The use function will close the resource as specified in the use documentation.