installer icon indicating copy to clipboard operation
installer copied to clipboard

Provide a reliable AdoptOpenJDK Registry Key for Windows

Open karianna opened this issue 6 years ago • 5 comments

Add a reliable registry key to find (so we can 'prefer' AdoptOpenJDK) on Windows.

FYI - When you run one of CL our windows installers there is a checkbox to say use Oracle registry keys (since a lot of software relies on that). I think we should write an equivalent reliable AdoptOpenJDK key if you don't select Oracle (or write one regardless of whether you do or not).

So far the only semi-reliable key we’ve found is: HKEY_LOCAL_MACHINE\SOFTWARE\Classes\AdoptOpenJDK.jarfile\shell\open\command 1h Tres Finocchiaro This points to: @=""C:\Program Files\AdoptOpenJDK\jdk-11.0.4.11-hotspot\bin\javaw.exe" -jar "%1" %*" Which can then be exploded into parts that would allude to the JDK home.

There are other keys that are registered at install time but contain hard-coded version information into the paths, making them hard to reliably locate. (edited)

karianna avatar Oct 13 '19 15:10 karianna

@karianna thanks for filing this...

For some more context... I'm writing a Windows desktop installer using NSIS and there are many examples online for fetching a registry key using Java's technique.

This will work if the JavaHome is configured, but since this is not default, it's not reliable.

!define JRE "Software\JavaSoft\Java Runtime Environment"

!macro _ReadReg
    ClearErrors
    ReadRegStr $0 HKLM "${JRE}" "CurrentVersion"
    ReadRegStr $0 HKLM "${JRE}\$0" "JavaHome"
    IfErrors +2 0
    StrCpy $0 "$0\bin\java.exe"
    IfFileExists "$0" Found ; jump to something called "Found:"
!macroend

The above technique is fairly simple and straightforward.

On the contrary -- since Adopt doesn't seem to have a similar key -- the logic is much more obscure. Worse, it requires use of poorly documented, poorly coded -- or in my trials non-working -- NSIS macros to grab the parts of the registry value used for install.

!define JRE "SOFTWARE\Classes\AdoptOpenJDK.jarfile\shell\open\command"

!macro _ReadAdoptKey
    ClearErrors
    ReadRegStr $0 HKLM "${JRE}" ""
    StrCpy $0 "$0" "" 1 ; Remove first double-quote
    ${IndexOf} $1 $0 "$\"" ; Find the index of second double-quote
    StrCpy $0 "$0" $1 ; Get the string section up to the index
    IfFileExists "$0" Found ; jump to something called "Found:"
!macroend

Although this is specific to NSIS, I'd think that any installer framework would benefit from preferring AdoptOpenJDK if that's the intention of the app developers.

This issue does't exist on MacOS or Linux because they each have their own technique for setting a preferred Java version, both of which seem fine with AdoptOpenJDK.

tresf avatar Oct 13 '19 17:10 tresf

What kind of tree and keys would simplify the discovery process ? Only a base key with one entry(key) for every jvm installed with installed path as value ? Wich naming scheme for the key ? Will it need to allow to sort jvm easily ? by version ? by release date ?

douph1 avatar Apr 19 '21 20:04 douph1

Here's how Zulu does it: https://docs.azul.com/zulu/zuludocs/ZuluUserGuide/Appendix/WindowsRegKeysAffbyZuluMSIinstall.htm

It may be beneficial to see how others do it and pick something that matches.

The specific versioning questions would be best handled by loosely adopting something like Oracle's technique and using some form of "CurrentVersion" value which is predictably available. Firefox uses a somewhat similar technique.

As far as I understand there's no easy support for "sorting" a registry by date or version, so any additional information would be to future-proof 3rd parties as well as Adoptium's installers. For example, currently Oracle will offer to remove old versions, if Adoptium wishes to do this, it may make such a feature (e.g. in an MSI installer that offers an unattended option to remove other versions) easier to author down the road.

ISVs needing this information would likely benefit from this information however unless its adopted by all JVM providers, I'm not sure how many developer would be interested in crawling it as a one-off. As long as there are so many JVM providers, ISVs have to decide how best to support all of them. Mimicking the historical registry layout would be the smallest barrier to entry for ISVs that way to take precedence with a particular provider, but without breaking compatibility with others.

tresf avatar Apr 19 '21 21:04 tresf

Here's how Zulu does it: https://docs.azul.com/zulu/zuludocs/ZuluUserGuide/Appendix/WindowsRegKeysAffbyZuluMSIinstall.htm

this link to Zulu seems to handle it exactly how I propose it :

Only a base key with one entry(key) for every jvm installed with installed path as value ?

So it may be something like : HKLM\SOFTWARE\Adoptium\Temurin\temurin--jre HKLM\SOFTWARE\WOW6432Node\Adoptium\temurin 32-bit\Temurin--jre HKLM\SOFTWARE\Adoptium\Temurin\temurin- HKLM\SOFTWARE\WOW6432Node\Adoptium\temurin 32-bit\Temurin- (I didn't like much the " 32bit" with space)

CurrentVersion is not well defined: What if we have 2 current version ? One for Hotspot and One for OpenJ9 ? One for JDK8LTS and JDK11LTS etc

Oracle as not well documented if CurrentVersion must be the last version installed, the higher available ..

As consquencies we alread see a drift : As you can see on your Oracle link https://www.oracle.com/java/technologies/javase/runtime-windows.html Oracle put only major version in CurrentVersion (no patch, no build number) ( as we do actually at Adopt ) But Zulu have already change this behaviour to set a more grainded version : "CurrentVersion"="8.0.282"

So I would like to know if the goal of this issue is only to provide a list ( each installer his own key ) and the others product choose in this list of available/installed jvm or if we need more .. a "pointer" to a specific version as SOFTWARE\Classes\AdoptOpenJDK.jarfile\shell\open\command (CurrentVersion is misleading to me and so not reliable I think)

douph1 avatar Apr 20 '21 07:04 douph1

CurrentVersion is not well defined: What if we have 2 current version ? One for Hotspot and One for OpenJ9 ? One for JDK8LTS and JDK11LTS etc

I fear you may never solve this problem. If you choose to, I've tried to explain the use-case (not the solution) here, quoting:

[...] there's no easy support for "sorting" [...]

ISVs needing this information would likely benefit from this information however unless its adopted by all JVM providers, I'm not sure how many developer would be interested in crawling it as a one-off. As long as there are so many JVM providers, ISVs have to decide how best to support all of them. Mimicking the historical registry layout would be the smallest barrier to entry for ISVs that way to take precedence with a particular provider, but without breaking compatibility with others.

Oracle did offer its own mixed Java support for Java Applets, however the concept of "CurrentVersion" was replaced with a UI helper in the Control Panel and normal Java apps didn't honor it. Perhaps you can add the entropy for major version and GC aside the keys in the registry at a predictable path, however I fear if the goal is to try to solve the various combinations of "CurrentVersion"'s that may exist... well I feel you may need a better use case then me.

To put it simply, if an ISV requires a system-wide version of Adoptium J9 is installed, but NOT HotSpot they aren't really handling Adoptium as a singleton app like the Java and Firefox examples provided previously. Note, to that point, Firefox does have a somewhat similar issue with it's Firefox ESR release and it uses a separate registry namespace (Mozilla Firefox ESR) for this edge-case as to not pollute their mainline release although even this convention seems to have changed over the years.

tresf avatar Apr 20 '21 07:04 tresf