Skip to content

Conversation

@gnodet
Copy link
Contributor

@gnodet gnodet commented May 26, 2023

JIRA issue: MTOOLCHAINS-49

Add mojos to:

  • display a human readable list of discovered JDK toolchains
  • generate the toolchains.xml file for discovered JDK toolchains
  • select a JDK toolchain with specific behaviour if the current JDK fulfils the requirements

The generation of the toolchains.xml file is not necessary to use discovered toolchains. The select-jdk-toolchain will select a toolchain amongst explicitely configured toolchains and discovered toolchains. The information for discovered toolchains are cached in ~/.m2/discovered-toolchains-cache.xml file by default.

The select-jdk-toolchain config below allows using the current JDK, or any other discovered JDK >= 17. The benefit is that the current JDK can be kept for speed, but ensuring the usage of any JDK 17 or higher if the current jdk is below the requirements.

   <profile>
      <id>toolchains</id>
      <build>
        <plugins>
          <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-toolchains-plugin</artifactId>
            <version>3.1.1-SNAPSHOT</version>
            <executions>
              <execution>
                <goals>
                  <goal>select-jdk-toolchain</goal>
                </goals>
                <configuration>
                  <version>[17,)</version>
                </configuration>
              </execution>
            </executions>
          </plugin>
        </plugins>
      </build>
    </profile>

The display-discovered-jdk-toolchains shows human readable discovered JDKs:

> mvn org.apache.maven.plugins:maven-toolchains-plugin:3.1.1-SNAPSHOT:display-discovered-jdk-toolchains
...
[INFO] Discovered 13 JDK toolchains:
[INFO]   - /Users/gnodet/.sdkman/candidates/java/21.ea.22-open
[INFO]     provides:
[INFO]       vendor: Oracle Corporation
[INFO]       runtime.version: 21-ea+22-1890
[INFO]       runtime.name: OpenJDK Runtime Environment
[INFO]       version: 21-ea
...

while the generate-jdk-toolchains-xml will write the output in xml format:

> mvn org.apache.maven.plugins:maven-toolchains-plugin:3.1.1-SNAPSHOT:generate-jdk-toolchains-xml 
...
<?xml version="1.0" encoding="UTF-8"?>
<toolchains xsi:schemaLocation="http://maven.apache.org/TOOLCHAINS/1.1.0 http://maven.apache.org/xsd/toolchains-1.1.0.xsd" xmlns="http://maven.apache.org/TOOLCHAINS/1.1.0"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <toolchain>
    <type>jdk</type>
    <provides>
      <vendor>Oracle Corporation</vendor>
      <runtime.version>21-ea+22-1890</runtime.version>
...

@gnodet gnodet force-pushed the discovered-toolchains branch 2 times, most recently from 74e3bba to 93918e2 Compare May 30, 2023 07:59
@gnodet gnodet force-pushed the discovered-toolchains branch from 93918e2 to 101cfec Compare May 30, 2023 22:29
@gnodet gnodet changed the title Add a mojo to display discovered toolchains Automatic discovery of toolchains May 31, 2023
@gnodet gnodet changed the title Automatic discovery of toolchains Automatic discovery of JDK toolchains May 31, 2023
Copy link
Contributor

@elharo elharo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is interesting. It probably should have a JIRA issue for release notes and discussion. I'm wondering if we add this functionality but eliminate a lot of the configuration by establishing some default rules along these lines.

@rmannibucau
Copy link

Cant we make toolchain.xml physically optional and replaced by some env var naming convention instead?
This way these new mojos are not needed and therefore no need to maintain the generated value which is a challenge to maintain until you make toolchain.xml an useless indirection using vars from my XP.
Sounds more natural to integrate with specific setups and CI and requires less effort for us IMHO.

@norrisjeremy
Copy link

Cant we make toolchain.xml physically optional and replaced by some env var naming convention instead? This way these new mojos are not needed and therefore no need to maintain the generated value which is a challenge to maintain until you make toolchain.xml an useless indirection using vars from my XP. Sounds more natural to integrate with specific setups and CI and requires less effort for us IMHO.

Wouldn't it be great if settings.xml could also be made optional by usage of env vars as well?

@rmannibucau
Copy link

@norrisjeremy sure but not on this pr I guess ;)

@gnodet
Copy link
Contributor Author

gnodet commented Feb 25, 2024

Cant we make toolchain.xml physically optional and replaced by some env var naming convention instead? This way these new mojos are not needed and therefore no need to maintain the generated value which is a challenge to maintain until you make toolchain.xml an useless indirection using vars from my XP. Sounds more natural to integrate with specific setups and CI and requires less effort for us IMHO.

Wouldn't it be great if settings.xml could also be made optional by usage of env vars as well?

Settings are already interpolated so we can use env vars already, I'm using it locally with the following:

    <mirror>
      <id>central</id>
      <mirrorOf>central</mirrorOf>
      <url>${env.MAVEN_CENTRAL}</url>
    </mirror>

so that I can point to a mirror on my LAN when available.

Toolchains are also interpolated and env vars seems to be supported too fwiw.

So it's not really settings being optional, but it's easy to setup a project's settings.xml or toolchains.xml that just use env variables, wouldn't that work ?

@rmannibucau
Copy link

are already interpolated

Yes this is what makes it complicated compared to not using it.
The main issue is that it is never maintained - env var are cause it is the only thing being updated and widely used.
So after some time you get a lot of pointless entries or entries pointing to path or env var not existing.
Indeed we can add yet another mojo to detect that, and another one to try to fix it but a working solution without any code sounds more seducing to me than a hard to use one with a lot of processes and code.

@norrisjeremy
Copy link

Wouldn't it be great if settings.xml could also be made optional by usage of env vars as well?

Settings are already interpolated so we can use env vars already, I'm using it locally with the following:

    <mirror>
      <id>central</id>
      <mirrorOf>central</mirrorOf>
      <url>${env.MAVEN_CENTRAL}</url>
    </mirror>

so that I can point to a mirror on my LAN when available.

Toolchains are also interpolated and env vars seems to be supported too fwiw.

So it's not really settings being optional, but it's easy to setup a project's settings.xml or toolchains.xml that just use env variables, wouldn't that work ?

The point is to have a standard method by which Maven can detect specific env vars for this without having to explicitly write a settings.xml or toolchains.xml, as it is an inconvenience to both generate and maintain these files.

Copy link
Contributor

@elharo elharo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

still needs docs, including site docs

@gnodet
Copy link
Contributor Author

gnodet commented Feb 27, 2024

Wouldn't it be great if settings.xml could also be made optional by usage of env vars as well?

Settings are already interpolated so we can use env vars already, I'm using it locally with the following:

    <mirror>
      <id>central</id>
      <mirrorOf>central</mirrorOf>
      <url>${env.MAVEN_CENTRAL}</url>
    </mirror>

so that I can point to a mirror on my LAN when available.
Toolchains are also interpolated and env vars seems to be supported too fwiw.
So it's not really settings being optional, but it's easy to setup a project's settings.xml or toolchains.xml that just use env variables, wouldn't that work ?

The point is to have a standard method by which Maven can detect specific env vars for this without having to explicitly write a settings.xml or toolchains.xml, as it is an inconvenience to both generate and maintain these files.

Let's put the settings.xml aside for this PR. This PR provides a ToolchainDiscover component which can be used to discover toolchains instead of having to write the toolchains.xml. It's just missing a few lines of code to add a discovery mechanism based on environment variables. What is the most used syntax to define those ? I can easily add it. @rmannibucau @norrisjeremy

@rmannibucau
Copy link

Personally i use JAVA${major}_HOME and wire it in pom in executable or jvm properties today.

But what I dont like in this pr is that it adds complexity to the complexity of toolchain whereas if you totally drop toolchain everything is simple.

Dont take it as a -1 but more as not something to promote nor recommend to end users IMHO.

@gnodet gnodet changed the title Automatic discovery of JDK toolchains [MTOOLCHAINS-49] Automatic discovery of JDK toolchains Feb 28, 2024
@gnodet
Copy link
Contributor Author

gnodet commented Feb 28, 2024

Personally i use JAVA${major}_HOME and wire it in pom in executable or jvm properties today.

But what I dont like in this pr is that it adds complexity to the complexity of toolchain whereas if you totally drop toolchain everything is simple.

Dont take it as a -1 but more as not something to promote nor recommend to end users IMHO.

I'm not sure how it really adds complexity. I agree toolchains can be seen as overly complicated when you can use the <jvm> arg for surefire. But the compiler cannot for example and in such cases, you have to use toolchains. So let's simplify their usage.

Note that with this PR, you don't have to generate the toolchains xml, they are automatically discovered. So with no toolchains preconfigured, if you have an env var JAVA17_HOME, you can very easily select it as the toolchain:

➜  maven-toolchains-plugin git:(discovered-toolchains) echo $JAVA17_HOME
/Users/gnodet/.sdkman/candidates/java/17.0.9-graalce
➜  maven-toolchains-plugin git:(discovered-toolchains) mvn org.apache.maven.plugins:maven-toolchains-plugin:3.1.1-SNAPSHOT:select-jdk-toolchain -Dtoolchain.jdk.env=JAVA17_HOME
Using MAVEN_CENTRAL=http://old-broken-macbook-pro.local:8082/artifactory/maven-remote/
[INFO] Scanning for projects...
[INFO] 
[INFO] ----------< org.apache.maven.plugins:maven-toolchains-plugin >----------
[INFO] Building Apache Maven Toolchains Plugin 3.1.1-SNAPSHOT
[INFO]   from pom.xml
[INFO] ----------------------------[ maven-plugin ]----------------------------
[INFO] 
[INFO] --- toolchains:3.1.1-SNAPSHOT:select-jdk-toolchain (default-cli) @ maven-toolchains-plugin ---
[INFO] Found 10 possible jdks: [/Users/gnodet/.sdkman/candidates/java/21.0.2-tem, /Users/gnodet/.jabba/jdk/zulu@1.8.282/Contents/Home, /Users/gnodet/.sdkman/candidates/java/8.0.402-librca, /Users/gnodet/.jbang/cache/jdks/17, /Users/gnodet/.sdkman/candidates/java/11.0.19-tem, /Users/gnodet/.sdkman/candidates/java/21.0.2-graalce, /Users/gnodet/.sdkman/candidates/java/17.0.9-graalce, /Users/gnodet/.sdkman/candidates/java/22.ea.31-open, /Library/Java/JavaVirtualMachines/zulu-8.jdk/Contents/Home, /Users/gnodet/.sdkman/candidates/java/17.0.10-tem]
[INFO] Discovered 10 JDK toolchains
[INFO] Found matching JDK toolchain: JDK[/Users/gnodet/.sdkman/candidates/java/17.0.9-graalce]
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time:  0.569 s
[INFO] Finished at: 2024-02-28T12:52:47+01:00
[INFO] ------------------------------------------------------------------------
➜  maven-toolchains-plugin git:(discovered-toolchains) 

If you want to compile targeting JDK 1.7 for example, you can select a JDK 1.8 compile by using -Dtoolchain.jdk.version="[1.8,1.9)" ...

@gnodet gnodet added this to the 3.2.0 milestone Feb 28, 2024
flags.computeIfAbsent(currentJdkHome, p -> new HashMap<>()).put(CURRENT, "true");
// check environment variables for JAVA{xx}_HOME
System.getenv().entrySet().stream()
.filter(e -> e.getKey().startsWith("JAVA") && e.getKey().endsWith("_HOME"))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe a regex including the digits?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure why, this test also captures JAVA_HOME which is fine. I'm not sure we need to restrict to using numbers, even if that's what people usually do. The only place it's used is when matching against a user supplied value in the env filter during selection, but it could be anything, especially something like: JAVA_GRAAL_17_HOME or whatever.

PersistedToolchains ps = new PersistedToolchains();
ps.setToolchains(tcs);
return ps;
} catch (Exception e) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can this be a more specific exception?

ps.setToolchains(tcs);
return ps;
} catch (Exception e) {
if (log.isDebugEnabled()) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The if block doesn't seem to do much.

More significantly I'm not sure this is the right error handling. Is it expected that there's an error discovering toolchains? if so, no message at all. If it's not expected, maybe always a message. What does it mean if the toolchains fail here?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My goal is the following: the toolchain discovery is optional, so any exception happening should be logged to the user but not forbid the use of the feature, in particular a later selection of the toolchain. Any exception caught is logged at WARNING level (with stack trace if debug is enabled).
This can be moved to the callers, though...

cache = new ConcurrentHashMap<>();
Path cacheFile = getCacheFile();
if (Files.isRegularFile(cacheFile)) {
try (Reader r = Files.newBufferedReader(cacheFile)) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

charset

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The charset used is deterministic, it's UTF-8 as indicated in the javadoc. I'm fine with this charset, so not sure why I would need to make it explicit.

}
}
} catch (IOException | XmlPullParserException e) {
log.warn("Error reading toolchains cache: " + e);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If the cache isn't read, what's the effect? if we just read directly without caching, then no warning should be logged. debug level at most.

How important is a cache here anyway? How long does it take to just recompute every time?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The cache is imho quite important. The length operation is the following:
https://github.com/gnodet/maven-toolchains-plugin/blob/1cd938cfa39b262e669378135b7df89559408300/src/main/java/org/apache/maven/plugins/toolchain/jdk/ToolchainDiscoverer.java#L142-L154
The java process is spawned for each JDK, so on my computer, it takes 950 ms (using a the parallel fork join pool). I'd rather avoid it each time the mojo is invoked.

But the cache is just a cache, if an error occurs while reading/writing, the process will still work, that's why errors are caught and logged at WARNING level. I'm not sure to understand the "if we just read directly without caching" sentence.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK, I'll buy the cache is important, but if this works when the cache fails then a warning is too high a log level since the user doesn't need to pay attention to it. This should be debug level.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note that the cache does not cache discovered toolchains (i.e. paths which contain a JDK), but rather the information related to each found JDK.

@mthmulders
Copy link

I've tested this on a Macbook, where I have all my JDKs installed through Homebrew. All of them have been discovered, so that's good!

But I've also tested this on a Windows machine, where I've used scoop to install two JDKs. The display-discovered-jdk-toolchains goal only discovers openjdk21 (the active one) but fails to discover openjdk17.

@gnodet
Copy link
Contributor Author

gnodet commented Mar 1, 2024

I've tested this on a Macbook, where I have all my JDKs installed through Homebrew. All of them have been discovered, so that's good!

But I've also tested this on a Windows machine, where I've used scoop to install two JDKs. The display-discovered-jdk-toolchains goal only discovers openjdk21 (the active one) but fails to discover openjdk17.

@mthmulders Do you know which paths they are installed to ?

@mthmulders
Copy link

@mthmulders Do you know which paths they are installed to ?

[INFO] Found 1 possible jdks: [C:\Users\<windows username>\scoop\apps\openjdk21\21.0.2-13]
[INFO] Discovered 1 JDK toolchains:
[INFO]   - C:\Users\<windows username>\scoop\apps\openjdk21\21.0.2-13
[INFO]     provides:
[INFO]       version: 21.0.2
[INFO]       runtime.name: OpenJDK Runtime Environment
[INFO]       runtime.version: 21.0.2+13-58
[INFO]       vendor: Oracle Corporation
[INFO]       current: true
[INFO]       lts: true
[INFO]       env: JAVA_HOME

But what I have on disk (reported on Git Bash, hence /c/, but you get the idea):

$ pwd
/c/Users/<windows username>/scoop/apps
$ ls -l openjdk*/
openjdk17/:
total 4
drwxr-xr-x 1 <windows username> 4096  0 Oct 27 08:27 17.0.2-8/
lrwxrwxrwx 1 <windows username> 4096 46 Oct 27 08:27 current -> /c/Users/<windows username>/scoop/apps/openjdk17/17.0.2-8/
 
openjdk21/:
total 8
drwxr-xr-x 1 <windows username> 4096  0 Oct 27 08:29 21.0.1-12/
drwxr-xr-x 1 <windows username> 4096  0 Feb 15 09:05 21.0.2-13/
lrwxrwxrwx 1 <windows username> 4096 47 Feb 15 09:05 current -> /c/Users/<windows username>/scoop/apps/openjdk21/21.0.2-13/

So, generally speaking, the path is C:\Users\<windows username>\scoop\apps\openjdk<major version>\<full version>\, and for convenience, there's a symlink C:\Users\<windows username>\scoop\apps\openjdk<major version>\current\ that points to the latest installed version for that major release.

They're all installed from https://github.com/ScoopInstaller/Java, by the way.

@gnodet
Copy link
Contributor Author

gnodet commented Mar 1, 2024

@mthmulders Do you know which paths they are installed to ?

[INFO] Found 1 possible jdks: [C:\Users\<windows username>\scoop\apps\openjdk21\21.0.2-13]
[INFO] Discovered 1 JDK toolchains:
[INFO]   - C:\Users\<windows username>\scoop\apps\openjdk21\21.0.2-13
[INFO]     provides:
[INFO]       version: 21.0.2
[INFO]       runtime.name: OpenJDK Runtime Environment
[INFO]       runtime.version: 21.0.2+13-58
[INFO]       vendor: Oracle Corporation
[INFO]       current: true
[INFO]       lts: true
[INFO]       env: JAVA_HOME

But what I have on disk (reported on Git Bash, hence /c/, but you get the idea):

$ pwd
/c/Users/<windows username>/scoop/apps
$ ls -l openjdk*/
openjdk17/:
total 4
drwxr-xr-x 1 <windows username> 4096  0 Oct 27 08:27 17.0.2-8/
lrwxrwxrwx 1 <windows username> 4096 46 Oct 27 08:27 current -> /c/Users/<windows username>/scoop/apps/openjdk17/17.0.2-8/
 
openjdk21/:
total 8
drwxr-xr-x 1 <windows username> 4096  0 Oct 27 08:29 21.0.1-12/
drwxr-xr-x 1 <windows username> 4096  0 Feb 15 09:05 21.0.2-13/
lrwxrwxrwx 1 <windows username> 4096 47 Feb 15 09:05 current -> /c/Users/<windows username>/scoop/apps/openjdk21/21.0.2-13/

So, generally speaking, the path is C:\Users\<windows username>\scoop\apps\openjdk<major version>\<full version>\, and for convenience, there's a symlink C:\Users\<windows username>\scoop\apps\openjdk<major version>\current\ that points to the latest installed version for that major release.

They're all installed from https://github.com/ScoopInstaller/Java, by the way.

Would you mind trying again ? I added support for discovery JDK inside ~\scoop\apps\* ...

@mthmulders
Copy link

mthmulders commented Mar 4, 2024

Would you mind trying again ? I added support for discovery JDK inside ~\scoop\apps\* ...

Sure! I don't have access to that Windows machine on a daily basis, so it took a while. Here are the results from commit f3b0b29:

[INFO] --- toolchains:3.1.1-SNAPSHOT:display-discovered-jdk-toolchains (default-cli) @ maven-toolchains-plugin ---
[INFO] Found 1 possible jdks: [C:\Users\<windows username>\scoop\apps\openjdk21\21.0.2-13]
[INFO] Discovered 1 JDK toolchains:
[INFO]   - C:\Users\<windows username>\scoop\apps\openjdk21\21.0.2-13
[INFO]     provides:
[INFO]       version: 21.0.2
[INFO]       runtime.name: OpenJDK Runtime Environment
[INFO]       runtime.version: 21.0.2+13-58
[INFO]       vendor: Oracle Corporation
[INFO]       current: true
[INFO]       lts: true
[INFO]       env: JAVA_HOME
[INFO] ------------------------------------------------------------------------

So it seems not to work yet, because in the meantime, to ensure proper testing, I have installed the following Java runtimes:

  • graalvm22-jdk17
  • openjdk17
  • openjdk21
  • semeru17-jdk
  • semeru-lts-jdk
  • zulu17-jdk

The code omits to navigate into the package directory; I've pushed a commit that does just that. Not sure if we only want the "current" version of each package, or in fact "all" versions of a package?

stream.forEach(dirsToTest::add);
// Scoop can install multiple versions of a Java distribution, we only take the one that is
// currently selected.
stream.map(path -> Paths.get(path.toString(), "current")).forEach(dirsToTest::add);
Copy link
Contributor Author

@gnodet gnodet Mar 5, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The goal is to find all JDK installed, not only the current one.

My undersanding is that they are installed by scoop in C:\Users\M67B014\scoop\apps\[jdk-name]\[version].
The installedDirs should then point to C:\Users\M67B014\scoop\apps\[jdk-name] because it's later scanned for JDK in its child directories, see

try (Stream<Path> stream = Files.list(dest)) {
stream.forEach(dir -> {
dirsToTest.add(dir);
dirsToTest.add(dir.resolve("Contents/Home"));
});

So by adding all direct children of scoop\apps, we should later have the children of those directories.

@mthmulders Are you sure the fix in line 414 is not sufficient ?

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll double-check again one of these days, but I'm pretty sure that <userHome>\scoop\apps is not enough. Scoop-installed Java runtimes reside under <userHome>\scoop\apps\<packageName>\<version>, with <userHome>\scoop\apps\<packageName>\current as a symlink to the currently active version of that package.

Regardless of that, the question remains: given that openjdk21 has three installed versions (21.0.0, 21.0.1 and 21.0.2), do we want all of them to be detected or only the current one?

Copy link
Contributor Author

@gnodet gnodet Mar 5, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll double-check again one of these days, but I'm pretty sure that <userHome>\scoop\apps is not enough. Scoop-installed Java runtimes reside under <userHome>\scoop\apps\<packageName>\<version>

I think the code was already checking those. installedDirs should contain all <userHome>\scoop\apps\<packageName> while dirsToTest should later contain all <userHome>\scoop\apps\<packageName>\<version>.

, with <userHome>\scoop\apps\<packageName>\current as a symlink to the currently active version of that package.

That one will be ignored, as symlinks are always transformed to a canonical path. That's the one stored in the toolchain.

Regardless of that, the question remains: given that openjdk21 has three installed versions (21.0.0, 21.0.1 and 21.0.2), do we want all of them to be detected or only the current one?

The code is currently written to get all JDK. The notion of current is specific to a given installer and may not be the latest one. We have heuristic to choose amongst multiple versions and the goal in the discovery phase is to escape from "just the one configured in the shell". So I'd rather have them all listed here and choose during toolchain matching / selection.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please see this gist. To create it, I've added some debug logging to print which directories indeed contain bin/javac or bin/javac.exe. I did that after the filter in line 444 to not print all packages I have installed that aren't a Java runtime.

If we only look at Paths.get(userHome, "scoop", "apps");, we will miss all installed runtimes - only the "current" one (which JAVA_HOME points to) will be detected. This is file-inspect-scoop-apps-packagename-txt.

Looking at the current directory under each installed package will make the code detect the current version of each installed Java runtime. So that is a lot more, but still not all. This is inspect-scoop-apps-packagename-current-txt.

To find all of them (as you wrote), we'd need to look at each subdirectory of an installed package. It will incur a lot of disk scanning, because it will inspect each installed version of each Scoop package, but it will even detect multiple versions of the same Java runtime (see openjdk21, microsoft17-jdk). This is inspect-scoop-apps-packagename-all-subdirs-txt. It will also report the current version of that package (so that's a duplicate), but we could filter those out I believe.

@mthmulders
Copy link

With your latest additions, the display-discovered-jdk-toolchains mojo reports 9 JDK toolchains, including the two versions of openjdk21 I have installed.

@gnodet
Copy link
Contributor Author

gnodet commented Mar 7, 2024

With your latest additions, the display-discovered-jdk-toolchains mojo reports 9 JDK toolchains, including the two versions of openjdk21 I have installed.

Yes, that was my initial idea. The goal is to discover all available JDK and then use some rules to select the one the user wants. There won't be exact doublons because symlinks are resolved to real path, so the "current" one won't be provided as a different JDK.

To select the matching JDK, we have multiple variables that can be used to match and sort JDKs. If that's not sufficient, the user can use the generate-jdk-toolchains-xml to generate a toolchains.xml file and hack it at will.
If disk scanning is too expensive, I'd rather provide a better heuristic (such as providing a glob to match scoop packages or something like that). I think we may have a missing cache so that we don't do the discovery more than once in a given maven session... I'll add that.

@gnodet
Copy link
Contributor Author

gnodet commented Mar 11, 2024

@mthmulders @elharo if there are no more concerns, I'll merge this PR

@mthmulders
Copy link

@mthmulders @elharo if there are no more concerns, I'll merge this PR

I didn't review the code thoroughly, I mainly chimed in to help get Scoop supported. Please go ahead, if other package managers should be added later we could always do that. I think those would make for great "up-for-grabs" issues.

@gnodet gnodet requested a review from slawekjaranowski March 18, 2024 07:08
@gnodet gnodet merged commit e22b3cf into apache:master Mar 20, 2024
@olamy olamy added the enhancement New feature or request label Apr 11, 2024
@jira-importer
Copy link

Resolve #107

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

10 participants