diff --git a/src/main/java/sbt_inc/CompilerBridgeFactory.java b/src/main/java/sbt_inc/CompilerBridgeFactory.java index ad6da308..8ea96a56 100644 --- a/src/main/java/sbt_inc/CompilerBridgeFactory.java +++ b/src/main/java/sbt_inc/CompilerBridgeFactory.java @@ -130,88 +130,101 @@ private static File getScala2CompilerBridgeJar( } if (!cachedCompiledBridgeJar.exists()) { - mavenLogger.info("Compiler bridge file is not installed yet"); - // compile and install - RawCompiler rawCompiler = - new RawCompiler( - scalaInstance, ClasspathOptionsUtil.auto(), new MavenLoggerSbtAdapter(mavenLogger)); - - File bridgeSources = - resolver.getJar(SBT_GROUP_ID, bridgeArtifactId, zincVersion, "sources").getFile(); - - Set bridgeSourcesDependencies = - resolver - .getJarAndDependencies(SBT_GROUP_ID, bridgeArtifactId, zincVersion, "sources") - .stream() - .filter( - artifact -> - artifact.getScope() != null && !artifact.getScope().equals("provided")) - .map(Artifact::getFile) - .map(File::toPath) - .collect(Collectors.toSet()); - - bridgeSourcesDependencies.addAll( - Arrays.stream(scalaInstance.allJars()) - .sequential() - .map(File::toPath) - .collect(Collectors.toList())); - - Path sourcesDir = Files.createTempDirectory("scala-maven-plugin-compiler-bridge-sources"); - Path classesDir = Files.createTempDirectory("scala-maven-plugin-compiler-bridge-classes"); - - IO.unzip(bridgeSources, sourcesDir.toFile(), AllPassFilter$.MODULE$, true); - - List bridgeSourcesScalaFiles = - FileUtils.listDirectoryContent( - sourcesDir, - file -> - Files.isRegularFile(file) && file.getFileName().toString().endsWith(".scala")); - List bridgeSourcesNonScalaFiles = - FileUtils.listDirectoryContent( - sourcesDir, - file -> - Files.isRegularFile(file) - && !file.getFileName().toString().endsWith(".scala") - && !file.getFileName().toString().equals("MANIFEST.MF")); - - try { - rawCompiler.apply( - IterableHasAsScala(bridgeSourcesScalaFiles).asScala().toSeq(), // sources:Seq[File] - IterableHasAsScala(bridgeSourcesDependencies).asScala().toSeq(), // classpath:Seq[File], - classesDir, // outputDirectory:Path, - IterableHasAsScala(Collections.emptyList()) - .asScala() - .toSeq() // options:Seq[String] - ); - - Manifest manifest = new Manifest(); - Path sourcesManifestFile = sourcesDir.resolve("META-INF").resolve("MANIFEST.MF"); - try (InputStream is = Files.newInputStream(sourcesManifestFile)) { - manifest.read(is); + // Install the compiler in a synchronized block to prevent multithreaded compiles to corrupt + // the installer. + synchronized (CompilerBridgeFactory.class) { + boolean compiledWasInstalledWhileThisThreadWasWaiting = cachedCompiledBridgeJar.exists(); + + if(compiledWasInstalledWhileThisThreadWasWaiting){ + return cachedCompiledBridgeJar; } - List> scalaCompiledClasses = - computeZipEntries(FileUtils.listDirectoryContent(classesDir, file -> true), classesDir); - List> resources = - computeZipEntries(bridgeSourcesNonScalaFiles, sourcesDir); - List> allZipEntries = new ArrayList<>(); - allZipEntries.addAll(scalaCompiledClasses); - allZipEntries.addAll(resources); - - IO.jar( - IterableHasAsScala( - allZipEntries.stream() - .map(x -> scala.Tuple2.apply(x._1, x._2)) - .collect(Collectors.toList())) - .asScala(), - cachedCompiledBridgeJar, - manifest); - - mavenLogger.info("Compiler bridge installed"); - - } finally { - FileUtils.deleteDirectory(sourcesDir); - FileUtils.deleteDirectory(classesDir); + mavenLogger.info("Compiler bridge file is not installed yet"); + // compile and install + RawCompiler rawCompiler = + new RawCompiler( + scalaInstance, ClasspathOptionsUtil.auto(), new MavenLoggerSbtAdapter(mavenLogger)); + + File bridgeSources = + resolver.getJar(SBT_GROUP_ID, bridgeArtifactId, zincVersion, "sources").getFile(); + + Set bridgeSourcesDependencies = + resolver + .getJarAndDependencies(SBT_GROUP_ID, bridgeArtifactId, zincVersion, "sources") + .stream() + .filter( + artifact -> + artifact.getScope() != null && !artifact.getScope().equals("provided")) + .map(Artifact::getFile) + .map(File::toPath) + .collect(Collectors.toSet()); + + bridgeSourcesDependencies.addAll( + Arrays.stream(scalaInstance.allJars()) + .sequential() + .map(File::toPath) + .collect(Collectors.toList())); + + Path sourcesDir = Files.createTempDirectory("scala-maven-plugin-compiler-bridge-sources"); + Path classesDir = Files.createTempDirectory("scala-maven-plugin-compiler-bridge-classes"); + + IO.unzip(bridgeSources, sourcesDir.toFile(), AllPassFilter$.MODULE$, true); + + List bridgeSourcesScalaFiles = + FileUtils.listDirectoryContent( + sourcesDir, + file -> + Files.isRegularFile(file) && file.getFileName().toString().endsWith(".scala")); + List bridgeSourcesNonScalaFiles = + FileUtils.listDirectoryContent( + sourcesDir, + file -> + Files.isRegularFile(file) + && !file.getFileName().toString().endsWith(".scala") + && !file.getFileName().toString().equals("MANIFEST.MF")); + + try { + rawCompiler.apply( + IterableHasAsScala(bridgeSourcesScalaFiles).asScala().toSeq(), // sources:Seq[File] + IterableHasAsScala(bridgeSourcesDependencies) + .asScala() + .toSeq(), // classpath:Seq[File], + classesDir, // outputDirectory:Path, + IterableHasAsScala(Collections.emptyList()) + .asScala() + .toSeq() // options:Seq[String] + ); + + Manifest manifest = new Manifest(); + Path sourcesManifestFile = sourcesDir.resolve("META-INF").resolve("MANIFEST.MF"); + try (InputStream is = Files.newInputStream(sourcesManifestFile)) { + manifest.read(is); + } + + List> scalaCompiledClasses = + computeZipEntries( + FileUtils.listDirectoryContent(classesDir, file -> true), classesDir); + List> resources = + computeZipEntries(bridgeSourcesNonScalaFiles, sourcesDir); + List> allZipEntries = new ArrayList<>(); + allZipEntries.addAll(scalaCompiledClasses); + allZipEntries.addAll(resources); + + IO.jar( + IterableHasAsScala( + allZipEntries.stream() + .map(x -> scala.Tuple2.apply(x._1, x._2)) + .collect(Collectors.toList())) + .asScala(), + cachedCompiledBridgeJar, + manifest); + + mavenLogger.info("Compiler bridge installed"); + + } finally { + FileUtils.deleteDirectory(sourcesDir); + FileUtils.deleteDirectory(classesDir); + } } }