package com.softwaremill.common.test.util; import com.dumbster.smtp.SimpleSmtpServer; import java.util.concurrent.Semaphore; /** * Use this instead of {@link com.dumbster.smtp.SimpleSmtpServer#start()}, as that implementation contains a * concurrency bug which may cause a lock: it may happen (and happens almost always on my machine) that notify() * is called before wait(), so then the wait() waits indifinetly. */ public class SimpleSmtpServerStarter { public static SimpleSmtpServer start(int port) { final SimpleSmtpServer server = new SimpleSmtpServer(port); final Semaphore waitingThreadEnteredSynchronized = new Semaphore(0); final Semaphore serverStarted = new Semaphore(0); // First we start a thread where we will wait for the server to startup. We only proceed after the new // thread entered the synchronized block, by waiting on a semaphore (waitingThreadEnteredSynchronized). new Thread() { @Override public void run() { // Block until the server socket is created synchronized (server) { waitingThreadEnteredSynchronized.release(); try { server.wait(); } catch (InterruptedException e) { // Ignore don't care. } serverStarted.release(); } } }.start(); try { waitingThreadEnteredSynchronized.acquire(1); } catch (InterruptedException e) { throw new RuntimeException(e); } // Then we start the server thread Thread t = new Thread(server); t.start(); // When the server is started, it calls notify, which in turn causes the serverStarted semaphore to be released. try { serverStarted.acquire(1); } catch (InterruptedException e) { throw new RuntimeException(e); } return server; } }