Bug 266086 - devel/cmake: cmake fails to find specific Java version when several Java versions are installed
Summary: devel/cmake: cmake fails to find specific Java version when several Java vers...
Status: Closed Works As Intended
Alias: None
Product: Ports & Packages
Classification: Unclassified
Component: Individual Port(s) (show other bugs)
Version: Latest
Hardware: Any Any
: --- Affects Only Me
Assignee: freebsd-kde (group)
URL: https://gitlab.kitware.com/cmake/cmak...
Keywords:
Depends on:
Blocks:
 
Reported: 2022-08-28 17:22 UTC by Yuri Victorovich
Modified: 2022-11-13 21:16 UTC (History)
5 users (show)

See Also:
bugzilla: maintainer-feedback? (kde)


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Yuri Victorovich freebsd_committer freebsd_triage 2022-08-28 17:22:36 UTC
This CMakeLists.txt:

> cmake_minimum_required(VERSION 3.15)
> find_package(Java 11 REQUIRED COMPONENTS Runtime)

fails to find Java 11:
> CMake Error at /usr/local/share/cmake/Modules/FindPackageHandleStandardArgs.cmake:230 (message):
>   Could NOT find Java: Found unsuitable version "1.8.0.342", but required is
>   at least "11" (found /usr/local/bin/java, found components: Runtime)
> Call Stack (most recent call first):
>   /usr/local/share/cmake/Modules/FindPackageHandleStandardArgs.cmake:592 (_FPHSA_FAILURE_MESSAGE)
>   /usr/local/share/cmake/Modules/FindJava.cmake:309 (find_package_handle_standard_args)
>   CMakeLists.txt:4 (find_package)

when several Java versions are installed:
> $ pkg info | grep -i openjdk
> bootstrap-openjdk17-17.0.1.12.1 Java Development Kit 17
> openjdk11-11.0.16+8.1          Java Development Kit 11
> openjdk17-17.0.4+8.1           Java Development Kit 17
> openjdk8-8.342.07.1            Java Development Kit 8


cmake-3.23.3
FreeBSD 13.1
Comment 1 Yuri Victorovich freebsd_committer freebsd_triage 2022-08-28 17:25:25 UTC
I discovered this problem while working on update of cad/surelog.
Comment 2 Yuri Victorovich freebsd_committer freebsd_triage 2022-08-28 17:29:51 UTC
When only openjdk11 is installed it is discovered fine by the above cmake script.
Comment 3 Tobias C. Berner freebsd_committer freebsd_triage 2022-08-29 07:59:49 UTC
Moin moin 

Could you provide your WIP update to cad/surelog, so that we have something to reproduce against?

mfg Tobias
Comment 4 Yuri Victorovich freebsd_committer freebsd_triage 2022-08-29 08:05:58 UTC
(In reply to Tobias C. Berner from comment #3)

Hi Tobias,


The cad/surelog update is committed but its build fails when Java versions other than the one required there (Java 17) are present.

It might also depend on the order in which Java versions were installed, I'm not sure.


Yuri
Comment 5 Tobias C. Berner freebsd_committer freebsd_triage 2022-08-29 08:09:47 UTC
(In reply to Yuri Victorovich from comment #4)

OK, I'll take a look :)

Have you already tried, whether just 
BINARY_ALIAS=java=${JAVA}
does the trick?

mfg Tobias
Comment 6 Yuri Victorovich freebsd_committer freebsd_triage 2022-08-29 08:18:18 UTC
(In reply to Tobias C. Berner from comment #5)

No, BINARY_ALIAS=java=${JAVA} doesn't help.
It always looks for /usr/local/bin/java.


Yuri
Comment 7 Dima Panov freebsd_committer freebsd_triage 2022-08-29 08:32:15 UTC
(In reply to Yuri Victorovich from comment #6)

Did you ever tried to force JAVA_PORT variable in port Makefile?
e.g. JAVA_PORT=java/openjdk17
Comment 8 Yuri Victorovich freebsd_committer freebsd_triage 2022-08-29 08:39:38 UTC
(In reply to Dima Panov from comment #7)

JAVA_PORT=java/openjdk17 doesn't help either.


Yuri
Comment 9 Tobias C. Berner freebsd_committer freebsd_triage 2022-08-29 09:01:08 UTC
From FindJava.cmake:

 10 This module finds if Java is installed and determines where the
 11 include files and libraries are.  The caller may set variable ``JAVA_HOME``
 12 to specify a Java installation prefix explicitly.


Apparently, setting the CMAKE_ARGS+=-DJAVA_HOME=${JAVA_HOME} does not work. 
But if you check /usr/local/share/cmake/Modules/CMakeFindJavaCommon.cmake you also see that it can source it from the environment variable JAVA_HOME.

If you set
CONFIGURE_ENV+=        JAVA_HOME=${JAVA_HOME}
then at least the configure stage passes without any issues.

Note: the CMakeLists contains some direct 'java' calls in custom_commands, so there are likely other issues :)


mfg Tobias
Comment 10 Yuri Victorovich freebsd_committer freebsd_triage 2022-08-29 16:12:37 UTC
It seems that cmake script should use ${JAVA_HOME}/bin/java instead of just "java". And if JAVA_HOME isn't set it can either try just "java", or fail.
Comment 11 Tobias C. Berner freebsd_committer freebsd_triage 2022-08-29 16:19:27 UTC
(In reply to Yuri Victorovich from comment #10)
It should generally use ${JAVA_HOME}/bin/java [1] -- what I meant is, that the custom-commands in surelog don't use ${Java_JAVA_EXECUTABLE} but 'java' -- so even if cmake were able to find the one you want, the target would still execute the one in path :)


[1] https://github.com/Kitware/CMake/blob/master/Modules/FindJava.cmake#L89
Comment 12 Yuri Victorovich freebsd_committer freebsd_triage 2022-08-29 16:44:25 UTC
(In reply to Tobias C. Berner from comment #11)

Ah, I see. Then there are 2 problems, one in cmake, and the other one in surelog. :-)
I first thought that both were in cmake.
I'll let them know.


Yuri
Comment 13 Adriaan de Groot freebsd_committer freebsd_triage 2022-11-13 10:10:29 UTC
After `find_package(Java)` you should be using `${Java_JAVA_EXECUTABLE}` or `${Java_JAVAC_EXECUTABLE}`, which will be the full path of the relevant executable: do not assume that they are in bin/ under the JAVA_HOME. Well, you can, and it'd be right most of the time, but there is a specific, explicit, variable for you to use.

The CMake code suggests that it does obey the CMake variable JAVA_HOME (if set) and also the environment variable, so there's some experimentation to be done between running-cmake-from-command-line and running-cmake-in-ports.
Comment 14 Adriaan de Groot freebsd_committer freebsd_triage 2022-11-13 21:16:38 UTC
CMake-time arguments -- how to get ports to do this is left as an exercise for the reader -- work. With a modified (to produce less output) CMakeLists.txt, with jdk 11, 17 and 8 installed, in that order, the following happens:

```
$ rm -rf build/ ; cmake -B build -S .
CMake Error at /usr/local/share/cmake/Modules/FindPackageHandleStandardArgs.cmake:230 (message):
  Could NOT find Java: Found unsuitable version "1.8.0.352", but required is
  at least "11" (found /usr/local/bin/java, found components: Runtime)
```

but I can set a version:

```
$ rm -rf build/ ; cmake -B build -S . -DJAVA_HOME=/usr/local/openjdk11/
-- Found Java: /usr/local/openjdk11/bin/java (found suitable version "11.0.17", minimum required is "11") found components: Runtime 
-- Configuring done
-- Generating done
-- Build files have been written to: /tmp/derp/build
```

or even a newer version:

```
$ rm -rf build/ ; cmake -B build -S . -DJAVA_HOME=/usr/local/openjdk17/
-- Found Java: /usr/local/openjdk17/bin/java (found suitable version "17.0.5", minimum required is "11") found components: Runtime 
-- Configuring done
-- Generating done
-- Build files have been written to: /tmp/derp/build
```

**do** ensure that that command-line argument gets to the CMake invocation.

Note that the executable /usr/local/bin/java is a symlink to a shellscript that does all *kinds* of stuff, which eventually runs one of the registered java executables. It doesn't offer an easy (except for the environment variable JAVA_HOME) way to select a particular Java VM.