Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Turning a listener into a future in java

Tags:

java

future

I'm trying to turn a listener into a Future, for asynchronous connection. I'm not used to using java futures yet, I've some experience with javascript promises but I fail to see how to write it in java (I've seen "CompletableFuture" in Java 8 may solve my problem, unfortunately I'm stuck with java 7). Here's what I've done so far:

public Future<Boolean> checkEmailClientConfiguration(final EmailClientConfiguration config) {
    final Future<Boolean> future = ???;
    // In some other languages I would create a deferred
    Transport transport = null;
    try {
        transport = session.getTransport("smtp");
        transport.addConnectionListener(new ConnectionListener() {
            @Override
            public void opened(ConnectionEvent connectionEvent) {
                System.out.println("!!!opened!!! ; connected=" + ((SMTPTransport) connectionEvent.getSource()).isConnected());
                // HERE I would like to make my future "resolved"
            }

            @Override
            public void disconnected(ConnectionEvent connectionEvent) {
            }

            @Override
            public void closed(ConnectionEvent connectionEvent) {
            }
        });
        transport.connect(config.getMailSMTPHost(),
                          config.getMailSMTPPort(),
                          config.getMailUsername(),
                          config.getMailPassword());
        return future;
    } catch (final MessagingException e) {
        throw e;
    } finally{
        if(transport != null){
            transport.close();
        }   
    }
}

I can't find any easy way to do it. The only solution I've found so far is to extend FutureTask and at the end of the Callable run, wait/sleep until some state variable is set as resolved. I don't really like the idea of waiting/sleeping in my business code, there is probably something that already exist to make it deferred? (in java, or popular libraries such as Apache commons or guava?)

like image 957
Joel Avatar asked Oct 30 '14 09:10

Joel


1 Answers

I finally got my answer from a colleague. What I'm looking for exists in Guava: SettableFuture. Here's how the code looks like:

    final SettableFuture<Boolean> future = SettableFuture.create();
    Transport transport = null;
    try {
        transport = session.getTransport("smtp");
        transport.addConnectionListener(new ConnectionListener() {
            @Override
            public void opened(ConnectionEvent connectionEvent) {
                future.set(((SMTPTransport) connectionEvent.getSource()).isConnected());
            }

            @Override
            public void disconnected(ConnectionEvent connectionEvent) {
            }

            @Override
            public void closed(ConnectionEvent connectionEvent) {
            }
        });
        transport.connect(config.getMailSMTPHost(),
                config.getMailSMTPPort(),
                config.getMailUsername(),
                config.getMailPassword());
    } catch (final MessagingException e) {
        future.setException(e);
    } finally{
        if(transport != null){
            transport.close();
        }
    }
    return future;
like image 119
Joel Avatar answered Nov 19 '22 22:11

Joel