mill icon indicating copy to clipboard operation
mill copied to clipboard

configure mill to use specific java version

Open axaluss opened this issue 2 years ago • 15 comments

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.

axaluss avatar Jan 12 '23 20:01 axaluss

one option might be .env/jenv support?

axaluss avatar Jan 12 '23 20:01 axaluss

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

lefou avatar Jan 12 '23 21:01 lefou

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?

axaluss avatar Feb 06 '23 19:02 axaluss

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.

lefou avatar Feb 06 '23 19:02 lefou

The intellij integration is crucial for adoption. Many companies have to use different java versions and being able to configure easily is important.

axaluss avatar Feb 09 '23 19:02 axaluss

Contributions are welcome.

lefou avatar Feb 09 '23 19:02 lefou

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.

Sailsman63 avatar Mar 06 '23 20:03 Sailsman63

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.

lefou avatar Mar 06 '23 20:03 lefou

Just took a peek at sbt repo, I don't think sbt use zinc API to run with custom JDK. What it does is:

  1. besides standard JAVA_HOME env var, the launch script also accept --java-home to override JAVA_HOME.
  2. when make bsp discovery json, instead of use sbt as first element of argv, it use java.home from jvm system property to construct java exec path as first element of argv.

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

chikei avatar Dec 22 '23 08:12 chikei

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

peter-fu avatar Aug 21 '24 09:08 peter-fu