From 14f958a32fa1f95d2495319c2c5aee0839bab1e2 Mon Sep 17 00:00:00 2001 From: Tobias Roeser Date: Thu, 27 Nov 2025 11:08:47 +0100 Subject: [PATCH 1/6] Make classgraphWorker AutoCloeable --- .../api/src/mill/javalib/classgraph/ClassgraphWorker.scala | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/libs/javalib/api/src/mill/javalib/classgraph/ClassgraphWorker.scala b/libs/javalib/api/src/mill/javalib/classgraph/ClassgraphWorker.scala index 8062b2073e15..0fee9c49c058 100644 --- a/libs/javalib/api/src/mill/javalib/classgraph/ClassgraphWorker.scala +++ b/libs/javalib/api/src/mill/javalib/classgraph/ClassgraphWorker.scala @@ -2,6 +2,10 @@ package mill.javalib.classgraph import mill.api.TaskCtx -trait ClassgraphWorker { +trait ClassgraphWorker extends AutoCloseable { def discoverMainClasses(classpath: Seq[os.Path])(using ctx: TaskCtx): Seq[String] + + override def close(): Unit = { + // noop + } } From e2eb41dcd915521f8cc5ab0b6c08fc1f673f4d93 Mon Sep 17 00:00:00 2001 From: Tobias Roeser Date: Thu, 27 Nov 2025 16:19:18 +0100 Subject: [PATCH 2/6] Make Scoverage worker AuotCloseable --- .../contrib/scoverage/api/ScoverageReportWorkerApi2.java | 7 ++++++- .../mill/contrib/scoverage/ScoverageReportWorker.scala | 8 +++++++- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/contrib/scoverage/api/src/mill/contrib/scoverage/api/ScoverageReportWorkerApi2.java b/contrib/scoverage/api/src/mill/contrib/scoverage/api/ScoverageReportWorkerApi2.java index a8cc276023b1..74ce9ce980f1 100644 --- a/contrib/scoverage/api/src/mill/contrib/scoverage/api/ScoverageReportWorkerApi2.java +++ b/contrib/scoverage/api/src/mill/contrib/scoverage/api/ScoverageReportWorkerApi2.java @@ -5,7 +5,7 @@ import java.nio.file.Files; import java.nio.file.Path; -public interface ScoverageReportWorkerApi2 { +public interface ScoverageReportWorkerApi2 extends AutoCloseable { interface Logger { void error(String msg); @@ -105,4 +105,9 @@ static void makeAllDirs(Path path) throws IOException { Files.createDirectories(path); } } + + @Override + default void close() throws Exception { + // no-op + } } diff --git a/contrib/scoverage/src/mill/contrib/scoverage/ScoverageReportWorker.scala b/contrib/scoverage/src/mill/contrib/scoverage/ScoverageReportWorker.scala index 925266fa1050..f89a45487cd4 100644 --- a/contrib/scoverage/src/mill/contrib/scoverage/ScoverageReportWorker.scala +++ b/contrib/scoverage/src/mill/contrib/scoverage/ScoverageReportWorker.scala @@ -11,7 +11,7 @@ import mill.contrib.scoverage.api.ScoverageReportWorkerApi2.{ } import os.Path -class ScoverageReportWorker { +class ScoverageReportWorker extends AutoCloseable { def bridge(classpath: Seq[PathRef]): ScoverageReportWorkerApiBridge = { def ctx0(using ctx: TaskCtx): ApiCtx = { @@ -74,6 +74,10 @@ class ScoverageReportWorker { )) } } + + override def close(): Unit = { + // no-op + } } object ScoverageReportWorker extends ExternalModule { @@ -101,5 +105,7 @@ object ScoverageReportWorker extends ExternalModule { def scoverageReportWorker: Task.Worker[ScoverageReportWorker] = Task.Worker { new ScoverageReportWorker() } + + // TODO: make protected lazy val millDiscover = Discover[this.type] } From 45583a017f71ab93ca836fee619c4d9bc7201413 Mon Sep 17 00:00:00 2001 From: Tobias Roeser Date: Thu, 27 Nov 2025 16:21:18 +0100 Subject: [PATCH 3/6] Make KSP worker AutoCloseable --- .../ksp2-api/src/mill/kotlinlib/ksp2/KspWorker.scala | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/libs/kotlinlib/ksp2-api/src/mill/kotlinlib/ksp2/KspWorker.scala b/libs/kotlinlib/ksp2-api/src/mill/kotlinlib/ksp2/KspWorker.scala index bc2e1f7d7d5c..9c42763a5bf3 100644 --- a/libs/kotlinlib/ksp2-api/src/mill/kotlinlib/ksp2/KspWorker.scala +++ b/libs/kotlinlib/ksp2-api/src/mill/kotlinlib/ksp2/KspWorker.scala @@ -1,6 +1,6 @@ package mill.kotlinlib.ksp2 -trait KspWorker { +trait KspWorker extends AutoCloseable { def runKsp( symbolProcessorClassloader: ClassLoader, @@ -8,4 +8,8 @@ trait KspWorker { symbolProcessingArgs: Seq[String] ): Unit + override def close(): Unit = { + // no-op + } + } From 4d2076974042a928ccafa45f2a760521936f181c Mon Sep 17 00:00:00 2001 From: Tobias Roeser Date: Thu, 27 Nov 2025 16:32:36 +0100 Subject: [PATCH 4/6] More workers --- .../src/mill/contrib/flyway/FlywayModule.scala | 13 +++++++++---- .../src/mill/playlib/RouteCompilerWorker.scala | 6 +++++- .../mill/playlib/RouteCompilerWorkerModule.scala | 1 + .../javalib/api/internal/InternalJvmWorkerApi.scala | 7 ++++++- .../src/mill/javalib/MavenWorkerSupport.scala | 3 +++ 5 files changed, 24 insertions(+), 6 deletions(-) diff --git a/contrib/flyway/src/mill/contrib/flyway/FlywayModule.scala b/contrib/flyway/src/mill/contrib/flyway/FlywayModule.scala index 3a76b6133dc0..bb9e1a01e24a 100644 --- a/contrib/flyway/src/mill/contrib/flyway/FlywayModule.scala +++ b/contrib/flyway/src/mill/contrib/flyway/FlywayModule.scala @@ -4,15 +4,18 @@ import mill.contrib.flyway.ConsoleLog.Level import org.flywaydb.core.Flyway import org.flywaydb.core.api.MigrationVersion import org.flywaydb.core.api.logging.LogFactory -import org.flywaydb.core.internal.configuration.{ConfigUtils => flyway} +import org.flywaydb.core.internal.configuration.ConfigUtils as flyway import org.flywaydb.core.internal.info.MigrationInfoDumper -import scala.jdk.CollectionConverters._ +import scala.jdk.CollectionConverters.* import mill.* import mill.api.PathRef +import mill.api.daemon.MillURLClassLoader import mill.javalib.{Dep, JavaModule} import org.flywaydb.core.api.output.{BaselineResult, CleanResult, MigrateOutput, MigrateResult} +import scala.annotation.nowarn + trait FlywayModule extends JavaModule { import FlywayModule._ @@ -34,10 +37,12 @@ trait FlywayModule extends JavaModule { .filter(_.nonEmpty) .map(key -> _) - def flywayClassloader = Task.Worker { + def flywayClassloader: Worker[MillURLClassLoader] = Task.Worker { mill.util.Jvm.createClassLoader(jdbcClasspath().map(_.path)) } - def flywayInstance = Task.Worker { + + @nowarn("msg=.*Workers should implement AutoCloseable.*") + def flywayInstance: Worker[Flyway] = Task.Worker { val jdbcClassloader = flywayClassloader() val configProps = Map(flyway.URL -> flywayUrl()) ++ diff --git a/contrib/playlib/src/mill/playlib/RouteCompilerWorker.scala b/contrib/playlib/src/mill/playlib/RouteCompilerWorker.scala index 330d5585ee91..e0e719d6084e 100644 --- a/contrib/playlib/src/mill/playlib/RouteCompilerWorker.scala +++ b/contrib/playlib/src/mill/playlib/RouteCompilerWorker.scala @@ -6,7 +6,7 @@ import mill.playlib.api.RouteCompilerType import mill.javalib.api.CompilationResult import mill.* -private[playlib] class RouteCompilerWorker { +private[playlib] class RouteCompilerWorker extends AutoCloseable { def compile( toolsClasspath: Seq[PathRef], @@ -48,6 +48,10 @@ private[playlib] class RouteCompilerWorker { case err => Result.Failure(err) } } + } + override def close(): Unit = { + // no-op + // TODO: cache classloader to improve repetitive compilations } } diff --git a/contrib/playlib/src/mill/playlib/RouteCompilerWorkerModule.scala b/contrib/playlib/src/mill/playlib/RouteCompilerWorkerModule.scala index c25870f0078d..054400d00208 100644 --- a/contrib/playlib/src/mill/playlib/RouteCompilerWorkerModule.scala +++ b/contrib/playlib/src/mill/playlib/RouteCompilerWorkerModule.scala @@ -4,6 +4,7 @@ import mill.{Module, Task, Worker} import mill.api.{Discover, ExternalModule} trait RouteCompilerWorkerModule extends Module { + def routeCompilerWorker: Worker[RouteCompilerWorker] = Task.Worker { new RouteCompilerWorker() } diff --git a/libs/javalib/api/src/mill/javalib/api/internal/InternalJvmWorkerApi.scala b/libs/javalib/api/src/mill/javalib/api/internal/InternalJvmWorkerApi.scala index 80fc4a236fa7..cab7b3f454d9 100644 --- a/libs/javalib/api/src/mill/javalib/api/internal/InternalJvmWorkerApi.scala +++ b/libs/javalib/api/src/mill/javalib/api/internal/InternalJvmWorkerApi.scala @@ -9,7 +9,7 @@ import mill.javalib.api.JvmWorkerApi.Ctx import mill.javalib.api.internal.ZincOp import os.Path -trait InternalJvmWorkerApi extends PublicJvmWorkerApi { +trait InternalJvmWorkerApi extends PublicJvmWorkerApi, AutoCloseable { /** Compile a Java-only project. */ def apply( @@ -119,7 +119,12 @@ trait InternalJvmWorkerApi extends PublicJvmWorkerApi { reportCachedProblems = false ) } + + override def close(): Unit = { + // bin-compat shim + } } + object InternalJvmWorkerApi { type Ctx = PublicJvmWorkerApi.Ctx } diff --git a/libs/javalib/src/mill/javalib/MavenWorkerSupport.scala b/libs/javalib/src/mill/javalib/MavenWorkerSupport.scala index b1be9466cfe0..275e1d16585a 100644 --- a/libs/javalib/src/mill/javalib/MavenWorkerSupport.scala +++ b/libs/javalib/src/mill/javalib/MavenWorkerSupport.scala @@ -5,6 +5,8 @@ import mill.javalib.publish.{Artifact, PublishInfo} import mill.util.Jvm import os.Path +import scala.annotation.nowarn + private[mill] trait MavenWorkerSupport extends CoursierModule with OfflineSupportModule { private def mavenWorkerClasspath: T[Seq[PathRef]] = Task { defaultResolver().classpath(Seq( @@ -21,6 +23,7 @@ private[mill] trait MavenWorkerSupport extends CoursierModule with OfflineSuppor Jvm.createClassLoader(classPath = classPath, parent = getClass.getClassLoader) } + @nowarn("msg=.*Workers should implement AutoCloseable.*") private[mill] def mavenWorker: Task.Worker[mill.javalib.internal.MavenWorkerSupport.Api] = Task.Worker { mavenWorkerClassloader().loadClass("mill.javalib.maven.worker.impl.WorkerImpl") From 2ec647686b1c300dca5afc7ddb8f3e70ecf0e8a5 Mon Sep 17 00:00:00 2001 From: Tobias Roeser Date: Thu, 27 Nov 2025 16:39:44 +0100 Subject: [PATCH 5/6] one worker more --- .../androidlib/databinding/AndroidDataBindingWorker.scala | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/libs/androidlib/databinding/src/mill/androidlib/databinding/AndroidDataBindingWorker.scala b/libs/androidlib/databinding/src/mill/androidlib/databinding/AndroidDataBindingWorker.scala index 91fe9f326c22..620767a7b291 100644 --- a/libs/androidlib/databinding/src/mill/androidlib/databinding/AndroidDataBindingWorker.scala +++ b/libs/androidlib/databinding/src/mill/androidlib/databinding/AndroidDataBindingWorker.scala @@ -1,6 +1,12 @@ package mill.androidlib.databinding -trait AndroidDataBindingWorker { +trait AndroidDataBindingWorker extends AutoCloseable { + def processResources(args: ProcessResourcesArgs): Unit + def generateBindingSources(args: GenerateBindingSourcesArgs): Unit + + override def close(): Unit = { + // no-up + } } From 984066c416bfcee924f44c17a8d02653150297bc Mon Sep 17 00:00:00 2001 From: Tobias Roeser Date: Thu, 27 Nov 2025 17:41:18 +0100 Subject: [PATCH 6/6] more worker --- .../src/mill/contrib/scalapblib/ScalaPBWorker.scala | 6 +++++- libs/util/src/mill/util/VisualizeModule.scala | 8 ++++++-- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/contrib/scalapblib/src/mill/contrib/scalapblib/ScalaPBWorker.scala b/contrib/scalapblib/src/mill/contrib/scalapblib/ScalaPBWorker.scala index f1be74b84b17..d95e978dc452 100644 --- a/contrib/scalapblib/src/mill/contrib/scalapblib/ScalaPBWorker.scala +++ b/contrib/scalapblib/src/mill/contrib/scalapblib/ScalaPBWorker.scala @@ -4,7 +4,7 @@ import mill.api.PathRef import java.io.File -class ScalaPBWorker { +class ScalaPBWorker extends AutoCloseable { private def scalaPB(scalaPBClasspath: Seq[PathRef])(using ctx: mill.api.TaskCtx) = { val instance = new ScalaPBWorkerApi { @@ -98,4 +98,8 @@ class ScalaPBWorker { ) mill.api.Result.Success(PathRef(dest)) } + + override def close(): Unit = { + // no-op + } } diff --git a/libs/util/src/mill/util/VisualizeModule.scala b/libs/util/src/mill/util/VisualizeModule.scala index e2cddfa27b69..db6886deb8f9 100644 --- a/libs/util/src/mill/util/VisualizeModule.scala +++ b/libs/util/src/mill/util/VisualizeModule.scala @@ -2,14 +2,16 @@ package mill.util import java.util.concurrent.LinkedBlockingQueue import coursier.core.Repository -import mill.api.{PathRef, Discover, Evaluator, ExternalModule, MultiBiMap, SelectMode} +import mill.api.{Discover, Evaluator, ExternalModule, MultiBiMap, PathRef, SelectMode} import mill.* -import mill.api.{Result} +import mill.api.Result import org.jgrapht.graph.{DefaultEdge, SimpleDirectedGraph} import guru.nidi.graphviz.attribute.Rank.RankDir import guru.nidi.graphviz.attribute.{Rank, Shape, Style} import mill.api.BuildCtx +import scala.annotation.nowarn + object VisualizeModule extends ExternalModule { def repositories: Seq[Repository] = coursier.Resolve.defaultRepositories @@ -62,6 +64,7 @@ object VisualizeModule extends ExternalModule { } } + // TODO: Remove bin-compat shim in Mill 2.x @deprecated("Use toolsClasspath instead", "0.13.0-M1") def classpath = toolsClasspath @@ -88,6 +91,7 @@ object VisualizeModule extends ExternalModule { * everyone can use to call into Graphviz, which the Mill execution threads * can communicate via in/out queues. */ + @nowarn("msg=.*Workers should implement AutoCloseable.*") private[mill] def worker: Worker[( LinkedBlockingQueue[( scala.Seq[Task.Named[Any]],