If you want to prevent the start of multiple instances of an application, it isn’t enough to check the existence of a (lock) file. Because if your application crashed this file can’t be cleaned up. Naturally the next start fails, even though another instance isn’t running. The solution is to use a lock on a file, because it lives and dies with the application.
The code above is a basic locking class:
/** * License GPLv2 */ public class Locker { /** The lock file. */ private static final File lockFile = new File("lock.lck"); private static FileChannel fileChannel = null; private static FileLock fileLock = null; /** True, if another instance is running. */ private static boolean isLocked = false; /** * Creates a file based lock. * * @throws RuntimeException, if an exception is happened while creating the lock * @return true, if a lock already exists, otherwise false. */ public static boolean lock() { // check, if a lock exists or lock it try { if (!lockFile.exists()) { lockFile.createNewFile(); fileChannel = new RandomAccessFile(lockFile, "rw").getChannel(); fileLock = fileChannel.lock(); } else { fileChannel = new RandomAccessFile(lockFile, "rw").getChannel(); try { fileLock = fileChannel.tryLock(); if (fileLock == null) isLocked = true; } catch (Exception e) { isLocked = true; } } } catch (Exception e) { System.out.println(e); throw new RuntimeException("Error while creating the lock [" + lockFile.getPath() + "]: " + e.getMessage(), e); } return isLocked; } public static void unlock() { // close lock socket try { fileLock.release(); fileChannel.close(); lockFile.delete(); isLocked = false; } catch (Exception e) { System.out.println("Error while closing the lock socket: " + e.getMessage()); } } public static boolean isLocked() { return isLocked; } }