tuhaihe commented on issue #150:
URL: https://github.com/apache/cloudberry-pxf/issues/150#issuecomment-5581957930
Root-caused this. Not a source or build-script bug -- two separate causes
stacked on top of
each other, which is why it looked so stubborn.
### Cause 1: on Debian/Ubuntu, `apt install maven` does not give you a JDK
Both distros got their Java the same way, as a side effect of installing
Maven, but the
dependency chains are not equivalent:
| | Java dependency of the `maven` package | `javac`? |
|---|---|---|
| Ubuntu 22.04 / 24.04 | `default-jre-headless \| <java7-runtime-headless>`
-- every alternative is a **`-jre-headless`** package | **no** |
| Rocky 9 / 10 | `maven-jdk-binding`, provided by `maven-openjdkNN`, which
pulls `java-NN-openjdk-devel` | yes |
So `dnf install maven` drags in a full JDK and the build passes on the first
try, while
`apt install maven` installs only a runtime. Confirmed against the project's
own CI images:
```
cbdb-build-rocky9 -> java-11-openjdk-devel
javac: yes
cbdb-build-rocky10 -> java-21-openjdk-devel
javac: yes
cbdb-build-ubuntu22.04-> openjdk-11-jre-headless, default-jre-headless
(auto) javac: NO
cbdb-build-ubuntu24.04-> (no java at all)
javac: NO
```
Two details make the Ubuntu side genuinely hard to spot:
- Debian/Ubuntu install the JRE into `/usr/lib/jvm/java-11-openjdk-amd64`,
the *same*
directory a JDK would occupy, so `ls /usr/lib/jvm` and `java -version`
both look healthy.
- Gradle's error names that very directory, which reinforces the impression
that Java 11 is
installed and fine.
There is simply no `bin/javac` in it, so `:pxf-api:compileJava` cannot
resolve a
`javaCompiler`. Note that
`ci/docker/pxf-cbdb-dev/common/script/build_pxf.sh:42` already
compensates -- it explicitly installs `openjdk-11-jdk` on apt systems and
`java-11-openjdk-devel` on dnf systems. CI therefore never hits this; only
people following
`README.md` do.
### Cause 2: after installing the JDK, a stale Gradle daemon replays the old
verdict
`server/gradle.properties` sets `org.gradle.daemon=true`. Gradle probes each
JVM
installation once and caches the result for the **lifetime of the daemon
process**, without
ever re-checking the filesystem. The failed first build leaves behind a
daemon that has
recorded `/usr/lib/jvm/java-11-openjdk-amd64` as having no `JAVA_COMPILER`.
Installing
`openjdk-11-jdk` then adds `javac` to that same directory -- but the *path*
is unchanged, so
Gradle treats it as the same JVM, reuses the existing daemon, and replays
the stale verdict.
Hence the identical error, in 2 seconds, without touching the disk.
### Reproduction
Clean `ubuntu:22.04` container, `2.2.0-incubating-rc1` source tree:
| Phase | Environment | Result |
|---|---|---|
| 1 | `openjdk-11-jre-headless` only | `Toolchain installation
'/usr/lib/jvm/java-11-openjdk-amd64' does not provide the required
capabilities: [JAVA_COMPILER]` |
| 2 | `openjdk-11-jdk` installed (`javac 11.0.32` present), daemon **not**
stopped | identical error, `BUILD FAILED in 2s` |
| 3 | same, after `./gradlew --stop` | `BUILD SUCCESSFUL in 23s` |
Phase 1 reproduces the first report, phase 2 the second. A clean Ubuntu
22.04 that installs
`openjdk-11-jdk` *before* the first build succeeds outright (`BUILD
SUCCESSFUL in 6m 10s`).
### Workaround
```bash
sudo apt-get install -y openjdk-11-jdk
export JAVA_HOME=/usr/lib/jvm/java-11-openjdk-amd64
cd server && ./gradlew --stop # required: the failed build left a
daemon behind
cd .. && make
```
Confirmed on both the Ubuntu 22.04 (JDK 11) and Ubuntu 24.04 (JDK 21) hosts
from the report.
### Proposed improvements
1. **The first failure is unhelpful.** Gradle starts happily on a JRE and
only fails later
at `:pxf-api:compileJava` with a message about toolchain capabilities
that never says
"you need a JDK". A preflight check in `server/Makefile` verifying
`$JAVA_HOME/bin/javac`
(or `javac` on `PATH`) before invoking Gradle turns this into an
actionable error.
2. **`README.md` is misleading on Debian/Ubuntu.** It says "JDK 1.8 or JDK
11" and suggests
`export JAVA_HOME=/usr/lib/jvm/java-11-openjdk` -- a RHEL-style path that
does not exist
on Debian/Ubuntu (`-amd64` suffix). It should say a JRE is insufficient,
give the package
names for apt and dnf, warn that `apt install maven` does **not** pull a
JDK (while
`dnf install maven` does), note that on Debian/Ubuntu a JRE occupies the
same
`/usr/lib/jvm/java-N-openjdk-amd64` path a JDK would, and mention that
installing the JDK
after a failed build requires `./gradlew --stop`.
I will open a PR with both.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]