- Published on
Git Hooks与多JDK环境问题解决
- Authors
- Name
- Cassian Florin
- @ynyng90660098
Git Hooks与多JDK环境问题解决
🧠 起因
公司使用了 git commit hook 在 git 提交之前对提交的内容与代码进行前置校验。 我本地存在多个 JDK 版本,最高版本为 JDK22,因此在使用 mvn 的 spotless 插件时会出现无法执行的问题。
Maven Spotless 插件执行失败
java.lang.reflect.InvocationTargetException: 'com.sun.tools.javac.tree.JCTree com.sun.tools.javac.tree.JCTree$JCImport.getQualifiedIdentifier()'
错误代码: 1
PATH: Maven spotless plugin execution
- JDK 版本不兼容导致的问题
- Spotless 插件与高版本 JDK 存在兼容性问题
- Git hooks 执行失败,阻止代码提交
错误日志示例:
[ERROR] Failed to execute goal com.diffplug.spotless:spotless-maven-plugin:2.30.0:apply(default-cli) on project qnvip-referral-client: Execution default-cli of goal com.diffplug.spotless:spotless-maven-plugin:2.30.0:apply failed: java.lang.reflect.InvocationTargetException: 'com.sun.tools.javac.tree.JCTree com.sun.tools.javac.tree.JCTree$JCImport.getQualifiedIdentifier()' -> [Help 1]
[ERROR]
[ERROR] To see the full stack trace of the errors, re-run Maven with the -e switch.
[ERROR] Re-run Maven using the -X switch to enable full debug logging.
[ERROR]
[ERROR] After correcting the problems, you can resume the build with the command
[ERROR] mvn <args> -rf :qnvip-referral-client
husky - pre-commit script failed (code 1)
💼 解决方案
考虑到或许有人会和我一样安装多个 JDK,因此结合这个情况与找到的资料,推荐使用 SDKMAN 来管理 Java 版本。
⚙️ 安装 SDKMAN
参考 SDKMAN 安装与配置指南 文档,其中对 Mac 系统环境与 Windows 系统环境的安装都有详细指导。
⚙️ 安装需要的 JDK
查看可用的 Java 版本
执行以下命令查看现在能使用的 Java 版本:
sdk list java
安装项目所需的 JDK
这个环境目前使用的是 JDK8。找到需要的版本后执行:
sdk install java 8.0.452-amzn
验证安装
安装完成后,验证 Java 版本:
java -version
预期输出:
openjdk version "1.8.0_452"
OpenJDK Runtime Environment (build 1.8.0_452-b08)
OpenJDK 64-Bit Server VM (build 25.452-b08, mixed mode)
🔧 在项目中配置 SDKMAN
项目目录结构
假设项目目录结构如下:
your-project/
├── .husky/
│ └── pre-commit
├── .sdkmanrc # sdkman配置
├── mvnw
├── mvnw.cmd
├── pom.xml
├── package.json
├── lint-staged.config.js
└── ...
创建 .sdkmanrc 配置文件
需要在项目根目录下配置 .sdkmanrc
文件,在其中写入 JDK 信息:
# This file is used by SDKMAN to automatically switch to the correct Java version
# when entering this project directory
#
# 注意:
# 1. 此文件需要 SDKMAN 支持才能生效
# 2. 如果您没有安装 SDKMAN,请参考 [SDKMAN 安装与配置指南](/blog/install-sdkman)
# 3. Windows 用户需要在 Git Bash 或类似的 Unix-like 环境中使用 SDKMAN
# 4. 如果您使用的是 IDE(如 IntelliJ IDEA),请确保在项目设置中也配置了正确的 JDK
#
# Note:
# 1. This file requires SDKMAN to take effect
# 2. If you haven't installed SDKMAN, please refer to the installation guide
# 3. Windows users need to use SDKMAN in Git Bash or similar Unix-like environment
# 4. If you're using an IDE (like IntelliJ IDEA), make sure to configure the correct JDK in project settings
java=8.0.452-amzn
🔧 配置 pre-commit Hook
完整的 pre-commit 脚本
这里是一个完整的 pre-commit 配置文件,支持跨平台使用:
#!/bin/sh
# Check if running on Windows or Unix-like system
case "$(uname -s)" in
MINGW*|MSYS*|CYGWIN*)
# Windows environment
IS_WINDOWS=true
SDKMAN_DIR="$USERPROFILE/.sdkman"
SDKMAN_INIT="$SDKMAN_DIR/bin/sdkman-init.sh"
;;
*)
# Unix-like environment (macOS, Linux, etc.)
IS_WINDOWS=false
SDKMAN_DIR="$HOME/.sdkman"
SDKMAN_INIT="$SDKMAN_DIR/bin/sdkman-init.sh"
;;
esac
# Check if .sdkmanrc file exists and SDKMAN is installed
if [ -f .sdkmanrc ] && [ -f "$SDKMAN_INIT" ]; then
echo "SDKMAN detected, activating project Java version"
# Load sdkman
source "$SDKMAN_INIT"
# Execute sdkman commands
sdk env
else
echo "SDKMAN not detected or .sdkmanrc not found. Using system Java version."
# Print current Java version for reference
if command -v java >/dev/null 2>&1; then
echo "Current Java version: $(java -version 2>&1 | head -n 1)"
else
echo "Warning: Java not found in PATH"
fi
fi
# Execute other pre-commit hooks
if [ -f "$HOME"/qnvip.gitconfig.sh ]; then
bash "$HOME"/qnvip.gitconfig.sh
fi
npx --no-install node .husky/scripts/modify-author-from-file.js
npx lint-staged --verbose --debug
脚本功能说明
这个脚本的主要功能: 1. 跨平台检测: 自动识别 Windows 和 Unix-like 系统 2. SDKMAN 集成: 自动加载 SDKMAN 并切换到项目指定的 Java 版本 3. 错误处理: 当 SDKMAN 不可用时,显示当前 Java 版本信息 4. 其他钩子: 执行额外的 Git hooks 和代码检查
✅ 验证配置
测试 Git Commit
配置完成后,尝试进行一次提交来验证配置是否正确:
git add .
git commit -m "test: 验证 SDKMAN 配置"
如果看到类似以下输出,说明配置成功:
SDKMAN detected, activating project Java version
Using java version 8.0.452-amzn in this shell.
常见问题排查
SDKMAN 未检测到
SDKMAN not detected or .sdkmanrc not found
错误代码: 0
PATH: Project directory
- SDKMAN 未正确安装
- .sdkmanrc 文件不存在
- 需要先安装 SDKMAN
解决方案: 参考 SDKMAN 安装与配置指南
Java 版本仍然不匹配
Java version mismatch in Git hooks
错误代码: 1
PATH: Git hooks execution
- SDKMAN 未正确加载
- 环境变量配置问题
- 需要检查 shell 配置
解决方案: 确保在 shell 配置文件中正确加载了 SDKMAN
🔗 关联内容
相关博客文章
- SDKMAN 安装与配置指南 - 详细的 SDKMAN 安装和配置步骤
- Git Hooks 与 Node 环境问题 - 解决 Git Hooks 中的 Node.js 环境问题
- 多环境 Git 配置管理 - 管理多个环境的 Git 配置
相关工具
- Husky - Git hooks 工具
- Lint-staged - 对暂存文件运行 linter
- Maven Spotless - 代码格式化插件
恭喜!现在你已经成功配置了 SDKMAN 来解决 Git Hooks 中的多 JDK 环境问题。这将确保你的团队使用统一的 Java 环境,避免版本冲突问题。