Configuring JVM Versions
By default, Mill uses the same JVM that it itself is running on to compile/test/run Java/Scala/Kotlin modules. This page goes into more detail about downloading and using a custom Java home on a per-module basis.
To override the default Java home, you can create a custom
JvmWorkerModule
and override the jvmWorker
method in your
JavaModule
or ScalaModule
by pointing it to that custom object:
Setting the JVM version of a JavaModule
The JvmWorkerModule.ForJvm
class takes a Jvm dependency string as its
contructor argument and configures the module to fetch and cache the Jvm
using coursier and use it for the compile, run, and test tasks.
The string has the form:
"{name}:{version}"
To see what Jvms are available for download look at the index for your os and architecture here.
import mill._, javalib._
import mill.define.ModuleRef
object JvmWorkerJava extends JvmWorkerModule {
def jvmId = "temurin:18.0.2"
}
object foo extends JavaModule {
def jvmWorker = ModuleRef(JvmWorkerJava)
object test extends JavaTests with TestModule.Junit4
}
> mill foo.run
Foo running on Java 18.0.2
> mill foo.test
Testing with JVM version: 18.0.2
Test foo.FooTest.testSimple finished...
Selecting a custom JVM via JvmWorkerModule.ForJvm
means that JVM is used for
compiling, testing, and running that module via Mill. Note that .assembly
is not
affected, as JVM assembly jars do not bundle a JVM and have to be run using a
JVM installed on the target host machine. Configuration is done via JvmWorkerModule
as the Zinc incremental compiler is used for compiling
Java and Scala sources.
Selecting JVM Index Versions
By default, Mill comes bundled with a version of the JVM index that was published when
each version of Mill is released. This ensures that the JVM versions you pick are stable,
but means that the latest JVM versions may not be available. You can pass in the JVM
index version explicitly via def jvmIndexVersion
below, choosing a published
index version from the Maven Central:
import scalalib._
object JvmWorkerJavaLatest extends JvmWorkerModule {
def jvmId = "temurin:23.0.1"
def jvmIndexVersion = "latest.release"
}
object bar extends ScalaModule {
def scalaVersion = "2.13.12"
def jvmWorker = ModuleRef(JvmWorkerJavaLatest)
}
> mill bar.run
Bar running on Java 23.0.1
Explicit JVM Download URLs
You can also pass in the JVM download URL explicitly. Note that if you do so, you need to ensure yourself that you are downloading the appropriate JVM distribution for your operating system and CPU architecture. In the example below we switch between Mac/ARM and Linux/X64, but you may have additional cases if you need to support Windows or other OS/CPU combinations
import kotlinlib._
object JvmWorkerJavaUrl extends JvmWorkerModule {
def jvmId =
if (sys.props("os.name") == "Mac OS X") {
"https://github.com/adoptium/temurin22-binaries/releases/download/jdk-22.0.2%2B9/OpenJDK22U-jdk_aarch64_mac_hotspot_22.0.2_9.tar.gz"
} else {
"https://github.com/adoptium/temurin22-binaries/releases/download/jdk-22.0.2%2B9/OpenJDK22U-jdk_x64_linux_hotspot_22.0.2_9.tar.gz"
}
}
object qux extends KotlinModule {
def kotlinVersion = "2.0.20"
def jvmWorker = ModuleRef(JvmWorkerJavaUrl)
}
> mill qux.run
Qux running on Java 22.0.2
Locally-Installed JVMs
Lastly, you can point Mill at any JVM distribution installed locally on disk via:
object JvmWorkerLocalJvm extends JvmWorkerModule {
def javaHome = Some(PathRef(os.Path("/my/java/home"), quick = true))
}
object baz extends JavaModule {
def jvmWorker = ModuleRef(JvmWorkerLocalJvm)
}