package de.norvos.utils; import java.net.InetAddress; import java.net.ServerSocket; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class ApplicationSingleton { private static boolean alreadyLocked = false; private static final Logger LOGGER = LoggerFactory.getLogger(ApplicationSingleton.class); private static boolean portLockingFailed; synchronized public static void checkAndLock() { if (!alreadyLocked) { final Thread t = new Thread(() -> { try { final InetAddress localhost = InetAddress.getByName("127.0.0.1"); @SuppressWarnings("resource") // this resource leak is final // intended: the socket // should only close when // the application closes. ServerSocket socket = new ServerSocket(Constants.SINGLETON_LOCK_PORT, 1, localhost); while (true) { socket.accept().close(); LOGGER.info( "Someone has connected to the locking port (port {}). The connection has thus been reset.", Constants.SINGLETON_LOCK_PORT); } } catch (final Exception e) { portLockingFailed = true; } } , "Port Locking Thread"); t.setDaemon(true); t.start(); try { Thread.sleep(1000); } catch (final InterruptedException e) { Thread.currentThread().interrupt(); LOGGER.info( "Waiting for the port locking to happen has failed. It is not safe starting the application now."); Errors.stopApplication(); throw new UnreachableCodeException(); } if (portLockingFailed) { LOGGER.info("Attempted to start already running application."); Errors.stopApplication(); throw new UnreachableCodeException(); } else { LOGGER.debug("Successfully locked on port {}.", Constants.SINGLETON_LOCK_PORT); alreadyLocked = true; } } } private ApplicationSingleton() { } }