Merge pull request #9574 from anatoliykmetyuk/br/fix-9343-export-pipelining

Ensure Java artifacts are exposed when usePipelining is set to true
This commit is contained in:
eugene yokota 2026-08-10 15:49:36 -04:00 committed by GitHub
commit b23891a643
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
8 changed files with 152 additions and 21 deletions

View File

@ -988,6 +988,22 @@ object Defaults extends BuildCommon with DefExtra {
val converter = fileConverter.value val converter = fileConverter.value
val cp = cp1.map(converter.toPath).map(converter.toVirtualFile) val cp = cp1.map(converter.toPath).map(converter.toVirtualFile)
opts.withClasspath(cp.toArray) opts.withClasspath(cp.toArray)
},
compileInputs2 := Def.uncached {
compileScalaBackend.value
val (_, _, packedBackendOutput) = compileIncremental.value
val inputs = compileInputs.value
val c = fileConverter.value
CompileInputs2(
packedBackendOutput +: data(dependencyClasspath.value).toVector,
sourcesVF.value,
scalacOptions.value.toVector,
javacOptions.value.toVector,
c.toVirtualFile(inputs.options.classesDirectory),
c.toVirtualFile(inputs.setup.cacheFile.toPath),
extraIncOptions.value.toVector,
scalaVersion.value,
)
} }
) )
) ++ ) ++
@ -2317,28 +2333,50 @@ object Defaults extends BuildCommon with DefExtra {
private val incCompiler = ZincUtil.defaultIncrementalCompiler private val incCompiler = ZincUtil.defaultIncrementalCompiler
private[sbt] def compileJavaTask: Initialize[Task[CompileResult]] = Def.task { private[sbt] def compileJavaTask: Initialize[Task[CompileResult]] = Def.task {
val s = streams.value val backendResult = compileScalaBackend.value
val projectId = thisProject.value.id val result = cachedCompileJavaTask.result.value
val r = compileScalaBackend.value
val in0 = (compileJava / compileInputs).value
val in = in0.withPreviousResult(PreviousResult.of(r.analysis, r.setup))
val reporter = (compile / bspReporter).value val reporter = (compile / bspReporter).value
val log = CompileDebugLogger(projectId, s.log) val inputs = (compileJava / compileInputs).value
try { val c = fileConverter.value
if (r.hasModified) { result match {
val result0 = incCompiler case Result.Value(hasModified) =>
.asInstanceOf[sbt.internal.inc.IncrementalCompilerImpl] val store = analysisStore(compileAnalysisFile.value.toPath(), c)
.compileAllJava(in, log) val contents = store.unsafeGet()
reporter.sendSuccessReport(result0.analysis()) reporter.sendSuccessReport(contents.getAnalysis())
result0.withHasModified(result0.hasModified || r.hasModified) CompileResult.of(
} else r contents.getAnalysis(),
} catch { contents.getMiniSetup(),
case NonFatal(e) => hasModified || backendResult.hasModified
reporter.sendFailureReport(in.options.sources) )
throw e case Result.Inc(cause) =>
reporter.sendFailureReport(inputs.options.sources)
throw cause
} }
} }
private val cachedCompileJavaTask = Def
.cachedTask {
val s = streams.value
val projectId = projectIdFromScope(s)
val in0 = (compileJava / compileInputs).value
val ci2 = (compileJava / compileInputs2).value
val c = fileConverter.value
val store = analysisStore(compileAnalysisFile.value.toPath(), c)
val previous = store.unsafeGet()
val in = in0.withPreviousResult(
PreviousResult.of(previous.getAnalysis(), previous.getMiniSetup())
)
val log = CompileDebugLogger(projectId, s.log)
val result = incCompiler
.asInstanceOf[sbt.internal.inc.IncrementalCompilerImpl]
.compileAllJava(in, log)
store.set(AnalysisContents.create(result.analysis(), result.setup()))
Def.declareOutput(c.toVirtualFile(in.setup.cacheFile.toPath))
Def.declareOutputDirectory(c.toVirtualFile(in.options.classesDirectory))
result.hasModified
}
.tag(Tags.Compile, Tags.CPU)
private def compileIncrementalTaskImpl( private def compileIncrementalTaskImpl(
task: BspCompileTask, task: BspCompileTask,
s: TaskStreams, s: TaskStreams,
@ -4415,9 +4453,9 @@ object Classpaths {
def makeProducts: Initialize[Task[Seq[File]]] = Def.task { def makeProducts: Initialize[Task[Seq[File]]] = Def.task {
val c = fileConverter.value val c = fileConverter.value
val resourceDirs = resourceDirectories.value val resourceDirs = resourceDirectories.value
val vfBackendDir = compileIncremental.value._2 compile.value
val backendDir = c.toPath(vfBackendDir) val backendDir = c.toPath(backendOutput.value)
val _ = resources.value resources.value
backendDir.toFile() :: resourceDirs.toList.filter(_.exists()) backendDir.toFile() :: resourceDirs.toList.filter(_.exists())
} }

View File

@ -0,0 +1,40 @@
ThisBuild / scalaVersion := "2.13.18"
ThisBuild / usePipelining := true
def countedCompilers(counter: File)(cs: xsbti.compile.Compilers): xsbti.compile.Compilers = {
val tools = cs.javaTools()
val underlying = tools.javac()
val counted = new xsbti.compile.JavaCompiler {
override def run(
sources: Array[xsbti.VirtualFile],
options: Array[String],
output: xsbti.compile.Output,
incToolOptions: xsbti.compile.IncToolOptions,
reporter: xsbti.Reporter,
log: xsbti.Logger
): Boolean = {
IO.append(counter, "javac\n")
underlying.run(sources, options, output, incToolOptions, reporter, log)
}
override def supportsDirectToJar(): Boolean =
underlying.supportsDirectToJar()
}
cs.withJavaTools(new xsbti.compile.JavaTools {
override def javac(): xsbti.compile.JavaCompiler = counted
override def javadoc(): xsbti.compile.Javadoc = tools.javadoc()
})
}
lazy val root = (project in file("."))
.aggregate(upstream, downstream)
lazy val upstream = project
.settings(
exportJars := true,
exportPipelining := false,
Compile / compilers ~= countedCompilers(file("javac-invocations")),
)
lazy val downstream = project
.dependsOn(upstream)

View File

@ -0,0 +1,7 @@
package example;
public class Greeter {
public static String greet(String name) {
return "Updated, " + name;
}
}

View File

@ -0,0 +1,5 @@
package example
object Marker {
val tag = "updated"
}

View File

@ -0,0 +1,8 @@
package example
object Main {
def run(): String = Greeter.greet("world")
def main(args: Array[String]): Unit =
assert(run() == "Updated, world")
}

View File

@ -0,0 +1,21 @@
> compile
$ exists target/**/upstream/classes/example/Greeter.class
$ exists target/**/downstream/classes/example/Main.class
$ copy-file javac-invocations javac-before
> compile
$ must-mirror javac-before javac-invocations
$ copy-file changes/Marker.scala upstream/src/main/scala/example/Marker.scala
> compile
$ copy-file changes/Greeter.java upstream/src/main/java/example/Greeter.java
> compile
> downstream / run
$ copy-file javac-invocations javac-after-java
$ delete target/out/jvm/scala-2.13.18/upstream/classes/example/Greeter.class
> compile
$ exists target/out/jvm/scala-2.13.18/upstream/classes/example/Greeter.class
$ must-mirror javac-after-java javac-invocations

View File

@ -0,0 +1,7 @@
package example;
public class Greeter {
public static String greet(String name) {
return "Hello, " + name;
}
}

View File

@ -0,0 +1,5 @@
package example
object Marker {
val tag = "upstream"
}