mill
mill copied to clipboard
configure mill to use specific java version
how can I tell mill to use a specific java version to compile/run the code/itself?
I have many different projects with many java versions.
one option might be .env/jenv support?
Currently, you can't select a different Java version than Mill itself runs with.
Zinc has support for it, by setting a jdkHome
, but this is currently not supported in Mill. It is probably not very difficult, as we already implemented non-local Java compiler support in the ZincWorkerImpl
. It's probably a matter of adding a new configuration target and make some changes in the worker to use a remote compiler with that setting.
As a workaround, you could start Mill with different JDKs. Mill supports the JAVA_HOME
env variable directly.
Just set the JAVA_HOME
environment variable, and Mill should respect it and use that version.
± java -version
openjdk version "17.0.3" 2022-04-19
OpenJDK Runtime Environment Temurin-17.0.3+7 (build 17.0.3+7)
OpenJDK 64-Bit Server VM Temurin-17.0.3+7 (build 17.0.3+7, mixed mode, sharing)
± mill --version
Mill Build Tool version 0.10.10
Java version: 17.0.3, vendor: Eclipse Adoptium, runtime: /opt/openjdk-bin-17.0.3_p7
Default locale: de_DE, platform encoding: UTF-8
OS name: "Linux", version: 5.15.80-gentoo-x86_64, arch: amd64
± JAVA_HOME=/opt/openjdk-bin-8 ./mill --version
Mill Build Tool version 0.10.10
Java version: 1.8.0_332, vendor: Temurin, runtime: /opt/openjdk-bin-8.332_p09/jre
Default locale: de_DE, platform encoding: UTF-8
OS name: "Linux", version: 5.15.80-gentoo-x86_64, arch: amd64
The tricky part here is to make intellij respect that setup. When i compile in intellij bsp project (from the build menu), it sometimes (depending on java setup order, but then consistently) used java 17 even though I set everything (global sdk, project sdk, module java versions, references in project xml, jenv, sdkman) to use java 11.
Is there a way to force bsp to use a certain environment? Is bsp using zinc and jdkHome would work? how can i tell intellij to pretty please use a certain environment?
Unfortunately I can't answer all these IntelliJ questions. Mill and Mill's BSP server is using zinc, but although zinc can run with a custom JDK home, we currently have it not implemented. An implementation would probably add some new javaHome
target in JavaModule
and pass it to the internal ZincWorkerImpl
when compiling. It doesn't sound that complicated, but it's also not trivial.
The intellij integration is crucial for adoption. Many companies have to use different java versions and being able to configure easily is important.
Contributions are welcome.
If someone were to want to work on this, (no promises at this time! I'm especially frustrated that zinc apparently has no documentation, not even scaladoc, so where does one even start?) what should it look like? Should it be just a way to pass an explicit path to zinc? Or should it be a little more sophisticated, something like gradle's "toolchain"?
Toolchain-like would provide the following:
- Build script declaration is short: Just specify the platform version that should be used, don't worry about locations/paths
- mill automatically finds a compatible JDK for the specified version, if already installed.
- (Optional) if no compatible platform installed, pull in as a build-time dependency.
I think a good start would be to analyze the same feature from sbt. I think, they require each user to have a local configuration file, which maps locally installed JDKs to names. These names can be referenced from the build file. Following this trace and settings keys in the sources might hopefully lead to the relevant zinc API. This is just from vague memory. I never used sbt to that extends and only skimmed the other day through some code/examples, but maybe it helps.
Just took a peek at sbt repo, I don't think sbt use zinc API to run with custom JDK. What it does is:
- besides standard JAVA_HOME env var, the launch script also accept
--java-home
to override JAVA_HOME. - when make bsp discovery json, instead of use
sbt
as first element ofargv
, it usejava.home
from jvm system property to construct java exec path as first element ofargv
.
I wonder if we can adapt this by adding --java-home
to launch script and write --java-home
and java.home
property to mill-bsp.json
how can I tell mill to use a specific java version to compile/run the code/itself?
I have many different projects with many java versions.
Same here.
My work around is adding the following line at the begining of the mill script (after the set -e
line).
JAVA_HOME=/Library/Java/JavaVirtualMachines/jdk-19.jdk/Contents/Home
Furthermore
I replaced the line with the following lines so that different developers may set different path of JDK of their own via .mill-java-home
file which is ignored by git by modifying .gitignore
.
if [ -f ".mill-java-home" ] ; then
JAVA_HOME="$(head -n 1 .mill-java-home 2> /dev/null)"
fi