fix: 彻底修复 Codespaces JDK 检测与 Gradle 构建

- JDK 检测: 用 glob 扫描 /usr/lib/jvm/java-17-openjdk-* 而非固定路径
- JDK 切换: 独立 switch_to_jdk17() — update-alternatives + JAVA_HOME + hash -r + 版本验证
- Gradle 强制: 通过 -Dorg.gradle.java.home= 硬性指定 JDK 17,绕过系统默认
- 构建前验证: java -version 确认 JDK 17,不通过则报错退出
- platform-tools 加入 PATH 供 adb 使用
- 移除 set -e,避免 update-alternatives 非零退出吞掉错误
This commit is contained in:
yuqianhe
2026-05-30 03:46:49 +00:00
parent cc06758098
commit 4acfeddaac

View File

@@ -14,7 +14,7 @@
# BUILD_TYPE — debug 或 release默认 debug
#
set -euo pipefail
# 注意: 不使用 set -e,因为部分命令(如 update-alternatives可能返回非零但可忽略
# ──────────────────────────────────────────────
# 颜色
@@ -41,7 +41,6 @@ BUILD_TYPE="${BUILD_TYPE:-debug}"
CMDLINE_TOOLS_URL="https://dl.google.com/android/repository/commandlinetools-linux-11076708_latest.zip"
SDK_MANAGER="$ANDROID_SDK_ROOT/cmdline-tools/latest/bin/sdkmanager"
# 需要安装的 SDK 组件
SDK_COMPONENTS=(
"platforms;android-34"
"build-tools;34.0.0"
@@ -56,13 +55,19 @@ JAVA17_HOME=""
install_jdk() {
info "检查 JDK 17 ..."
# 看是否已安装
if [ -d /usr/lib/jvm/java-17-openjdk-amd64 ]; then
JAVA17_HOME=/usr/lib/jvm/java-17-openjdk-amd64
# 先看系统是否已有 JDK 17 安装(可能在 /usr/lib/jvm 下)
local found_jdk=""
for dir in /usr/lib/jvm/java-17-openjdk-*; do
if [ -d "$dir" ] && [ -f "$dir/bin/java" ]; then
found_jdk="$dir"
break
fi
done
if [ -n "$found_jdk" ]; then
JAVA17_HOME="$found_jdk"
log "JDK 17 已安装,路径: $JAVA17_HOME"
export JAVA_HOME="$JAVA17_HOME"
export PATH="$JAVA_HOME/bin:$PATH"
java -version 2>&1 | head -1
switch_to_jdk17
return
fi
@@ -70,24 +75,64 @@ install_jdk() {
sudo apt-get update -qq
sudo apt-get install -y -qq openjdk-17-jdk-headless
JAVA17_HOME=/usr/lib/jvm/java-17-openjdk-amd64
# 通过 update-alternatives 强制设为默认
if [ -f "$JAVA17_HOME/bin/java" ]; then
sudo update-alternatives --set java "$JAVA17_HOME/bin/java" 2>/dev/null || true
export JAVA_HOME="$JAVA17_HOME"
export PATH="$JAVA_HOME/bin:$PATH"
log "JDK 17 设为默认成功"
else
warn "JDK 17 未安装在标准路径,尝试 locate ..."
JAVA17_HOME=$(dirname "$(dirname "$(readlink -f "$(which java)")")" 2>/dev/null || echo "")
if [ -n "$JAVA17_HOME" ]; then
export JAVA_HOME="$JAVA17_HOME"
export PATH="$JAVA_HOME/bin:$PATH"
# 安装后再查找
for dir in /usr/lib/jvm/java-17-openjdk-*; do
if [ -d "$dir" ] && [ -f "$dir/bin/java" ]; then
JAVA17_HOME="$dir"
break
fi
done
if [ -z "$JAVA17_HOME" ]; then
# 兜底
JAVA17_HOME="/usr/lib/jvm/java-17-openjdk-amd64"
fi
java -version 2>&1 | head -1
log "JDK 17 安装路径: $JAVA17_HOME"
switch_to_jdk17
}
# 统一 JDK 切换逻辑
switch_to_jdk17() {
if [ ! -f "$JAVA17_HOME/bin/java" ]; then
err "JDK 17 未找到可执行文件: $JAVA17_HOME/bin/java"
err "请手动安装: sudo apt-get install openjdk-17-jdk-headless"
exit 1
fi
# 1) update-alternatives 切换系统默认
if command -v update-alternatives &>/dev/null; then
sudo update-alternatives --set java "$JAVA17_HOME/bin/java" 2>/dev/null || true
sudo update-alternatives --set javac "$JAVA17_HOME/bin/javac" 2>/dev/null || true
fi
# 2) 强制设置环境变量(对 Gradle 子进程生效)
export JAVA_HOME="$JAVA17_HOME"
export PATH="$JAVA_HOME/bin:$PATH"
# 3) 刷新 shell 命令缓存
hash -r 2>/dev/null || true
# 4) 验证
local ver
ver=$(java -version 2>&1 | head -1)
if echo "$ver" | grep -q 'version "17'; then
log "JDK 17 已激活: $ver"
else
# 如果系统默认 java 仍不是 17用 JAVA_HOME 路径直接调用
local jdk_ver
jdk_ver=$("$JAVA_HOME/bin/java" -version 2>&1 | head -1)
if echo "$jdk_ver" | grep -q 'version "17'; then
warn "系统默认 java 为 $ver,但 JAVA_HOME 指向 JDK 17 ($jdk_ver)"
warn "构建时将强制使用 JAVA_HOME 路径"
# 将 alias 设到路径上
alias java="$JAVA_HOME/bin/java"
else
err "JDK 17 切换失败!当前: $ver, JAVA_HOME: $jdk_ver"
err "尝试手动: sudo update-alternatives --config java"
exit 1
fi
fi
}
# ──────────────────────────────────────────────
@@ -103,10 +148,9 @@ install_sdk() {
mkdir -p "$ANDROID_SDK_ROOT"
cd "$ANDROID_SDK_ROOT"
local zip_file="cmdline-tools.zip"
curl -fsSL "$CMDLINE_TOOLS_URL" -o "$zip_file"
unzip -q "$zip_file"
rm -f "$zip_file"
curl -fsSL "$CMDLINE_TOOLS_URL" -o cmdline-tools.zip
unzip -q cmdline-tools.zip
rm -f cmdline-tools.zip
# 整理目录结构: 需要 cmdline-tools/latest/bin/sdkmanager
mkdir -p cmdline-tools/latest
@@ -116,28 +160,29 @@ install_sdk() {
mv cmdline-tools/NOTICE.txt cmdline-tools/latest/ 2>/dev/null || true
mv cmdline-tools/source.properties cmdline-tools/latest/ 2>/dev/null || true
fi
log "命令行工具安装完成"
fi
# 接受所有 licenses(非交互)
# 接受 licenses
info "接受 SDK licenses ..."
yes | "$SDK_MANAGER" --licenses 2>&1 | tail -3 || true
yes | "$SDK_MANAGER" --licenses 2>&1 | tail -1 || true
# 安装必要组件(逐一带 yes 管道防卡死)
info "安装 SDK 组件(首次较慢,可能需要 1-2 分钟)..."
# 安装组件
info "安装 SDK 组件(首次较慢, 1-2 分钟)..."
for component in "${SDK_COMPONENTS[@]}"; do
# 检查是否已安装
local dir_path="${component/;/\/}"
if [ -d "$ANDROID_SDK_ROOT/$dir_path" ]; then
log " 已安装: $component"
continue
fi
info " 安装: $component ..."
yes | "$SDK_MANAGER" "$component" 2>&1 || true
yes | "$SDK_MANAGER" "$component" 2>&1 | tail -1 || true
log " done: $component"
done
# 将 platform-tools 加入 PATH供 adb 使用)
export PATH="$ANDROID_SDK_ROOT/platform-tools:$PATH"
log "Android SDK 就绪"
}
@@ -158,7 +203,7 @@ setup_local_properties() {
echo "sdk.dir=$ANDROID_SDK_ROOT"
echo "org.gradle.jvmargs=-Xmx2g -XX:MaxMetaspaceSize=512m"
} > "$props"
log "local.properties 已生成"
log "local.properties 已生成 ($props)"
}
# ──────────────────────────────────────────────
@@ -169,14 +214,13 @@ setup_gradle_wrapper() {
log "Gradle Wrapper 已存在"
return
fi
info "Gradle Wrapper 缺失,正在生成 ..."
if ! command -v gradle &>/dev/null; then
sudo apt-get install -y -qq gradle > /dev/null 2>&1
fi
cd "$PROJECT_DIR"
gradle wrapper --gradle-version 8.5 > /dev/null 2>&1
chmod +x gradlew
log "Gradle Wrapper 已生成 (v8.5)"
}
@@ -184,41 +228,81 @@ setup_gradle_wrapper() {
# 阶段 5构建 APK
# ──────────────────────────────────────────────
build_apk() {
info "验证构建环境 ..."
# 检查 JDK 版本
local java_ver
java_ver=$(java -version 2>&1 | head -1)
if ! echo "$java_ver" | grep -q 'version "17'; then
warn "系统 java 为: $java_ver"
warn "尝试用 JAVA_HOME 指向 JDK 17 ..."
if [ -n "$JAVA_HOME" ] && [ -f "$JAVA_HOME/bin/java" ]; then
local jdk17_ver
jdk17_ver=$("$JAVA_HOME/bin/java" -version 2>&1 | head -1)
if echo "$jdk17_ver" | grep -q 'version "17'; then
log "使用 JAVA_HOME 路径: $jdk17_ver"
else
err "JAVA_HOME 指向的也不是 JDK 17: $jdk17_ver"
exit 1
fi
else
err "JAVA_HOME 未设置或指向无效路径"
exit 1
fi
else
log "JDK 正确: $java_ver"
fi
# 检查 Android SDK
export ANDROID_SDK_ROOT
export JAVA_HOME
export PATH="$JAVA_HOME/bin:$ANDROID_SDK_ROOT/platform-tools:$PATH"
info "开始构建 $BUILD_TYPE APK ..."
cd "$PROJECT_DIR"
export ANDROID_SDK_ROOT
export JAVA_HOME
export PATH="$JAVA_HOME/bin:$PATH"
# 检查 gradlew
if [ ! -f gradlew ]; then
setup_gradle_wrapper
fi
# GRadle 参数:显式指定 java.home 避免使用系统默认 JDK
local gradle_args=(
"-Dorg.gradle.java.home=$JAVA_HOME"
"--no-daemon"
)
if [ "$BUILD_TYPE" = "release" ]; then
warn "Release 构建需要 keystore尝试构建 ..."
./gradlew assembleRelease 2>&1 || true
./gradlew "${gradle_args[@]}" assembleRelease 2>&1 || true
else
./gradlew assembleDebug 2>&1
./gradlew "${gradle_args[@]}" assembleDebug 2>&1
fi
local exit_code=$?
echo ""
local apk_path
apk_path=$(find "$PROJECT_DIR/app/build/outputs/apk" -name "*.apk" 2>/dev/null | head -5)
if [ -n "$apk_path" ]; then
if [ $exit_code -ne 0 ]; then
warn "构建失败(退出码: $exit_code"
warn "常见原因:"
warn " - 网络超时导致依赖下载失败 → 重试即可"
warn " - SDK 组件未安装完整 → 检查上方日志"
warn " - 内存不足Codespaces 免费 4GB→ 重试或加 --no-daemon"
warn ""
warn "重试命令:"
warn " cd $PROJECT_DIR && ./gradlew -Dorg.gradle.java.home=$JAVA_HOME --no-daemon assembleDebug"
return
fi
# 查找 APK
local apk_list
apk_list=$(find "$PROJECT_DIR/app/build/outputs/apk" -name "*.apk" 2>/dev/null)
if [ -n "$apk_list" ]; then
log "构建成功APK 文件:"
echo "$apk_path" | while read -r f; do
local size
size=$(du -h "$f" | cut -f1)
echo "$apk_list" | while read -r f; do
echo " $(ls -lh "$f" 2>/dev/null | awk '{print $5, $NF}')"
done
else
warn "未找到 APK 输出,检查上方日志。"
warn "常见原因:"
warn " - SDK 组件未安装完整"
warn " - Gradle 依赖下载失败(重试 ./gradlew assembleDebug"
warn " - 内存不足Codespaces 免费版 4GB可加 --no-daemon"
warn "未找到 APK 输出(可能构建未完成)"
fi
}
@@ -233,7 +317,8 @@ echo ""
echo " 项目目录: $PROJECT_DIR"
echo " SDK 路径: $ANDROID_SDK_ROOT"
echo " 构建类型: $BUILD_TYPE"
echo " JDK: $(java -version 2>&1 | head -1 || echo '(待安装)')"
echo " 初始 JDK: $(java -version 2>&1 | head -1)"
echo " JAVA_HOME: ${JAVA_HOME:-"(未设置)"}"
echo ""
install_jdk
@@ -243,12 +328,16 @@ setup_gradle_wrapper
build_apk
echo ""
if [ -f "$PROJECT_DIR/app/build/outputs/apk/debug/app-debug.apk" ]; then
local_apk="$PROJECT_DIR/app/build/outputs/apk/debug/app-debug.apk"
if [ -f "$local_apk" ]; then
log "APK 已就绪!"
echo " 下载: Codespaces 文件面板中找到并右键下载"
echo " 安装: adb install -r app/build/outputs/apk/debug/app-debug.apk"
echo " 文件: $local_apk"
echo " 安装: adb install -r $local_apk"
else
echo -e "${YELLOW}提示: 若因网络超时失败,重试一次即可${NC}"
echo -e "${YELLOW} cd $PROJECT_DIR && ./gradlew assembleDebug --no-daemon${NC}"
echo ""
echo -e "${YELLOW}══════════════════════════════════════════${NC}"
echo -e "${YELLOW} 构建未成功,请重试:${NC}"
echo -e "${YELLOW} cd $PROJECT_DIR && ./build.codespace.sh${NC}"
echo -e "${YELLOW}══════════════════════════════════════════${NC}"
fi
echo ""