diff --git a/src/main/scala/gitbucket/core/plugin/PluginRegistory.scala b/src/main/scala/gitbucket/core/plugin/PluginRegistory.scala index 042cb07..bd0c3e2 100644 --- a/src/main/scala/gitbucket/core/plugin/PluginRegistory.scala +++ b/src/main/scala/gitbucket/core/plugin/PluginRegistory.scala @@ -2,7 +2,8 @@ import java.io.{File, FilenameFilter, InputStream} import java.net.URLClassLoader -import java.nio.file.{Paths, StandardWatchEventKinds} +import java.nio.channels.{FileChannel, FileLock} +import java.nio.file.{Paths, StandardOpenOption, StandardWatchEventKinds} import java.util.Base64 import javax.servlet.ServletContext @@ -194,6 +195,23 @@ } } + private def copyFile(from: File, to: File, retry: Int = 0): Unit = { + using(FileChannel.open(from.toPath(), StandardOpenOption.CREATE, StandardOpenOption.WRITE)){ fc => + using(fc.tryLock()){ lock => + if(lock == null){ + if(retry >= 3){ // Retry max 3 times + logger.info(s"Retire to load: ${from.getAbsolutePath}") + } else { + Thread.sleep(500) + copyFile(from, to, retry + 1) + } + } else { + FileUtils.copyFile(from, to) + } + } + } + } + /** * Initializes all installed plugins. */ @@ -216,7 +234,7 @@ files.foreach { pluginJar => // Copy the plugin jar file to GITBUCKET_HOME/plugins/.installed val installedJar = new File(installedDir, pluginJar.getName) - FileUtils.copyFile(pluginJar, installedJar) + copyFile(pluginJar, installedJar) val classLoader = new URLClassLoader(Array(installedJar.toURI.toURL), Thread.currentThread.getContextClassLoader) try {