Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

configure mill to use specific java version #2250

Closed
axaluss opened this issue Jan 12, 2023 · 16 comments
Closed

configure mill to use specific java version #2250

axaluss opened this issue Jan 12, 2023 · 16 comments

Comments

@axaluss
Copy link

axaluss commented Jan 12, 2023

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
Copy link
Author

axaluss commented Jan 12, 2023

one option might be .env/jenv support?

@lefou
Copy link
Member

lefou commented Jan 12, 2023

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

@axaluss
Copy link
Author

axaluss commented Feb 6, 2023

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?

@lefou
Copy link
Member

lefou commented Feb 6, 2023

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.

@axaluss
Copy link
Author

axaluss commented Feb 9, 2023

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

@lefou
Copy link
Member

lefou commented Feb 9, 2023

Contributions are welcome.

@Sailsman63
Copy link

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.

@lefou
Copy link
Member

lefou commented Mar 6, 2023

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.

@chikei
Copy link
Contributor

chikei commented Dec 22, 2023

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

@peter-fu
Copy link

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

@llvee
Copy link

llvee commented Sep 23, 2024

@lefou
Is a better solution than the above two suggested solutions you posted still wanted for this?

@lefou
Copy link
Member

lefou commented Sep 23, 2024

@llvee I think everything proposed above are either workarounds or just ideas.

Ideally, we can declare an optional JVM/JDK version in a Java module, and Mill is either automatically fetching and using it if not present, or has some other means of accessing this JVM/JDK version (local config file, env variable, ...). E.g. older JDKs from Oracle can't be downloaded automatically in a legal way. Some users might also want to use patched JDKs (thinking of VMs with hot class replacement setups).

@llvee
Copy link

llvee commented Sep 23, 2024

Ok, is the ideal solution expected to also focus on IntelliJ compatibility? From my understanding, the desired outcome is that Mill can be used with any project, understand/use the correct JDK based on individual projects using JAVA_HOME env. Is that correct?

@lefou
Copy link
Member

lefou commented Oct 2, 2024

The system environment variable JAVA_HOME is already respected by Mill, so that Mill itself used the JDK it points to. The point about this issue is, that a JavaModule should be technically independent of the JVM Mill runs with, but can use whatever it is configured to. So, if you for some reasons need to build a module with Java 23, we want to be able to use some new jdkHome task and use that to build the module. Ideally, we also add a jdkVersion task, so we can default-implement jdkHome with some retrieval logic derived from that version. But ultimately, the user should have the freedom to use an arbitrary local JDK. Both should return some Options, to simply use the system default JVM.

The retrieval logic could be just downloading and caching it. Since older JDKs often imposed download restrictions, other build tools sometimes invented some config file and required the user to download and configure JDKs for later use. Whatever we end with, it should come with reasonable documentation.

Ideally, we also support these new configurations in GenIdea and BSP. Can't tell, if IDEA supports this per module or just for the whole project.

@lefou
Copy link
Member

lefou commented Oct 10, 2024

We should therefore aim for a solution that can be applied to all kind of SDKs.

One proposal is to look up a local config that matches the configured jdkVersion from a file under .config/mill-jdk.<version>. Additionally we could support some env var pattern like MILL_JDK_<version>_DIR.

@lihaoyi
Copy link
Member

lihaoyi commented Nov 20, 2024

Should be mostly resolved by #3716 which would go out next releaes 0.12.3

@lihaoyi lihaoyi closed this as completed Nov 20, 2024
@lefou lefou added this to the 0.12.3 milestone Nov 21, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

7 participants