Groovy(Java)でアプリケーションの二重起動を禁止する方法

Groovyに限ったことではないが、アプリケーションの二重起動を防止する方法をメモ。

以下のように、ファイルチャネルからロック取得が成功するかどうかで二重起動を防止できる。

Attach API( Oracle Technology Network for Java Developers )というのを利用しても実現できるらしいが、IcedTea、Linuxjdkのいずれにも標準装備されていないようなので断念した。(ClassNotFountExceptionが発生)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
#!/usr/bin/env groovy
import java.nio.channels.*

class Lock {
    public static boolean getLock() {
        final FileOutputStream fos = new FileOutputStream(new File("lock"))
        final FileChannel fc = fos.channel
        final FileLock lock = fc.tryLock()

        if (lock == null) {
            return false
        }

        Runtime.runtime.addShutdownHook {
            if (lock != null && lock.valid) {
                lock.release()
            }
            fc.close()
            fos.close()
        } as Thread
        return true
    }
}

// ここからはLockクラスを利用した二重起動チェック処理
if (!Lock.getLock()) {
    println "end"
    System.exit(1)
}

// 安心して処理を実行♪
Thread.start {
    while(true) {
        println "test"
        sleep(1000)
    }
}

Lock#getLock() メソッド実行結果が true ならロック取得成功、 false ならロック取得失敗となる。 上記スクリプトを2つ以上起動させようとしても後で起動した方が異常終了するようになる。