diff --git a/README.md b/README.md index fcb51ad4c..0be14cd26 100755 --- a/README.md +++ b/README.md @@ -69,11 +69,16 @@ To build PXF, you must have: source /usr/local/cloudberry-db/cloudberry-env.sh # For Cloudberry 2.1+ ``` -3. JDK 1.8 or JDK 11 to compile/run +3. A full JDK -- 1.8, 11, 17, or 21 -- to compile/run. A JRE is not enough, as the + server module needs `javac`. + + > [!NOTE] + > Support for JDK 1.8 will be removed in PXF 3.0. Use JDK 11 or later for new setups. Export your `JAVA_HOME`: ``` - export JAVA_HOME=/usr/lib/jvm/java-11-openjdk + export JAVA_HOME=/usr/lib/jvm/java-11-openjdk-amd64 # Debian/Ubuntu + export JAVA_HOME=/usr/lib/jvm/java-11-openjdk # RHEL/Rocky ``` 4. Go (1.25 or later) @@ -96,6 +101,8 @@ To build PXF, you must have: PXF uses Makefiles to build its components. PXF server component uses Gradle that is wrapped into the Makefile for convenience. +If the build fails, see [TROUBLESHOOTING.md](TROUBLESHOOTING.md#build-issues). + > [!NOTE] > To comply with Apache Software Foundation release guidelines, `gradle-wrapper.jar` is not included in the source distribution. It will be downloaded automatically during the initial build. Please ensure you have an active and stable internet connection. @@ -163,7 +170,7 @@ We provide a Docker-based development environment that includes Cloudberry, Hado - Start IntelliJ. Click "Open" and select the directory to which you cloned the `pxf` repo. - Select `File > Project Structure`. -- Make sure you have a JDK (version 1.8) selected. +- Make sure you have a JDK selected (1.8, 11, 17, or 21). CI builds with JDK 11 by default. - In the `Project Settings > Modules` section, select `Import Module`, pick the `pxf/server` directory and import as a Gradle module. You may see an error saying that there's no JDK set for Gradle. Just cancel and retry. It goes away the second time. - Import a second module, giving the `pxf/automation` directory, select "Import module from external model", pick `Maven` then click Finish. diff --git a/TROUBLESHOOTING.md b/TROUBLESHOOTING.md index a7d09ceba..4b7cf79ee 100644 --- a/TROUBLESHOOTING.md +++ b/TROUBLESHOOTING.md @@ -1,5 +1,46 @@ # Troubleshooting +## Build Issues + +### Gradle reports `does not provide the required capabilities: [JAVA_COMPILER]` + +``` +Execution failed for task ':pxf-api:compileJava'. +> Error while evaluating property 'javaCompiler' of task ':pxf-api:compileJava'. + > Toolchain installation '/usr/lib/jvm/java-11-openjdk-amd64' does not provide + the required capabilities: [JAVA_COMPILER] +``` + +The JVM Gradle is running on has no `javac`, so it is a JRE rather than a JDK. +Gradle itself starts fine on a JRE, which is why the build gets as far as +`:pxf-api:compileJava` before failing. Install a JDK and point `JAVA_HOME` at it: + +``` +# Debian/Ubuntu +sudo apt-get install -y openjdk-11-jdk +export JAVA_HOME=/usr/lib/jvm/java-11-openjdk-amd64 + +# RHEL/Rocky +sudo dnf install -y java-11-openjdk-devel +export JAVA_HOME=/usr/lib/jvm/java-11-openjdk +``` + +Two things make this easy to misdiagnose: + +* On Debian/Ubuntu the JRE is installed into `/usr/lib/jvm/java-11-openjdk-amd64`, + the same directory a JDK would use, so `java -version` and `ls /usr/lib/jvm` both + look healthy while `javac` is absent. The `maven` package depends on + `default-jre-headless` and does **not** pull in a JDK. (On RHEL/Rocky, + `dnf install maven` does install one, via `maven-jdk-binding`.) +* Installing the JDK is not sufficient on its own. The Gradle daemon caches JVM + installation metadata for its whole lifetime and never re-checks the filesystem, + and because the JDK lands in the same *path*, Gradle reuses the daemon left behind + by the failed build and reports the identical error. Stop it first: + + ``` + cd server && ./gradlew --stop + ``` + ## Out of Memory Issues ### diff --git a/server/Makefile b/server/Makefile index bfd0ee344..ee268517f 100644 --- a/server/Makefile +++ b/server/Makefile @@ -27,8 +27,31 @@ PXF_API_VERSION ?= $(shell cat $(PXF_ROOT_DIR)/api_version) PXF_GRADLE_PROPERTIES = -Pversion=$(PXF_VERSION) -PapiVersion=$(PXF_API_VERSION) +# Gradle can start on a JRE, but compiling PXF needs a JDK. Detect a JRE-only +# installation here so the build fails with an actionable message instead of +# Gradle's "does not provide the required capabilities: [JAVA_COMPILER]". +JAVAC := $(if $(JAVA_HOME),$(JAVA_HOME)/bin/javac,$(shell command -v javac 2>/dev/null)) + +.PHONY: check-jdk +check-jdk: + @if [ ! -x "$(JAVAC)" ]; then \ + echo "ERROR: no Java compiler (javac) found -- a JDK is required to build PXF, a JRE is not enough."; \ + if [ -n "$(JAVA_HOME)" ]; then \ + echo " JAVA_HOME=$(JAVA_HOME) has no bin/javac, so it points at a JRE."; \ + else \ + echo " JAVA_HOME is not set and javac is not on PATH."; \ + fi; \ + echo " Install a JDK and point JAVA_HOME at it, for example:"; \ + echo " Debian/Ubuntu: sudo apt-get install -y openjdk-11-jdk"; \ + echo " RHEL/Rocky: sudo dnf install -y java-11-openjdk-devel"; \ + echo " export JAVA_HOME=/usr/lib/jvm/java-11-openjdk-amd64"; \ + echo " If a build already failed here, also run './gradlew --stop'."; \ + echo " See TROUBLESHOOTING.md for details."; \ + exit 2; \ + fi + .PHONY: prepare-gradle-wrapper -prepare-gradle-wrapper: +prepare-gradle-wrapper: check-jdk @APP_HOME="$(CURDIR)" bash ./gradlew-install.sh help: