本文发布于292天前,最后更新于 292 天前,其中的信息可能已经有所发展或是发生改变。
我使用 sdkman 来管理多个 java 版本,每次在终端输入
java -version时都岁月静好,直到今天使用 gradle 编译项目时,却突然举着告示牌抗议:「找不到JDK,罢工了!」重新查看日志,原来是
macos自带的/usr/libexec/java_home程序不识别sdkman安装的java,所以需要我们通过一些小 trick 来骗过macos,使得sdkman安装的java也能被系统识别到。为了增强文章阅读的趣味性,这篇文章我试着使用 ai 来润色和生成文本,今后我的博客也会更多的借助
aigc的力量,来辅助我讲清楚一些容易被我遗漏的知识细节,让后来的初学者也能更容易理解我的解决思路,并复现我的技术解决方案。
/Library/Java/JavaVirtualMachines高档小区,每户都有:
Contents/Home(真实住宅)Info.plist(房产证明)~/.sdkman的集装箱公寓,只有:
# 在苹果JDK小区买个虚拟房产
sudo mkdir -p /Library/Java/JavaVirtualMachines/sdkman-current/Contents
# 创建跨次元传送门(<YOUR_USERNAME>替换为你的用户名)
sudo ln -s /Users/<YOUR_USERNAME>/.sdkman/candidates/java/current \
/Library/Java/JavaVirtualMachines/sdkman-current/Contents/Home
<!-- 伪造Info.plist文件 -->
cat <<EOF | sudo tee /Library/Java/JavaVirtualMachines/sdkman-current/Contents/Info.plist
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleIdentifier</key>
<string>sdkman.current</string>
<key>CFBundleName</key>
<string>SDKMAN Current JDK</string>
<key>JavaVM</key>
<dict>
<key>JVMPlatformVersion</key>
<string>9999</string>
<key>JVMVendor</key>
<string>Homebrew</string>
<key>JVMVersion</key>
<string>9999</string>
</dict>
</dict>
</plist>
EOF
# 查看当前JDK路径
/usr/libexec/java_home
应该输出:
/Library/Java/JavaVirtualMachines/sdkman-current/Contents/Home
查看所有已识别JDK
/usr/libexec/java_home -V
输出示例:
Matching Java Virtual Machines (1):
9999 (arm64) "Homebrew" - "SDKMAN Current JDK" /Library/Java/JavaVirtualMachines/sdkman-current/Contents/Home
/Library/Java/JavaVirtualMachines/sdkman-current/Contents/Home
| 系统行为 | 我们的伪装术 |
|---|---|
| 扫描标准JDK目录 | 创建虚拟目录结构 |
| 检查Info.plist合法性 | 伪造包含必要字段的配置文件 |
| 验证JVM实际存在 | 符号链接指向真实SDKMAN路径 |
版本号9999的阴谋:通过设置超高版本号,确保系统总是优先选择我们的「超级JDK」
java_home依然装瞎三连诊断术
ls -l /Library/Java/JavaVirtualMachines/sdkman-current/Contents/Home # 检查传送门是否畅通
plutil -lint Info.plist # 验证身份证是否伪造成功
java -version # 确认SDKMAN当前JDK是否正常
# 总操作流程图
+------------------+ +------------------+ +------------------+
| 伪造JDK别墅 | | 创建传送门 | | 办理9999号身份证 |
| mkdir -p |------>| ln -s |------>| Info.plist |
+------------------+ +------------------+ +------------------+
为什么java_home这么固执?
就像机场安检员坚持要检查登机牌,java_home的设计哲学是:
# 在XCode中优雅调用(Build Phase脚本示例)
export JAVA_HOME=$(/usr/libexec/java_home)
./gradlew build --stacktrace # 现在可以愉快甩锅给Android Studio了
本文发布于292天前,最后更新于 292 天前,其中的信息可能已经有所发展或是发生改变。
我使用 sdkman 来管理多个 java 版本,每次在终端输入
java -version时都岁月静好,直到今天使用 gradle 编译项目时,却突然举着告示牌抗议:「找不到JDK,罢工了!」重新查看日志,原来是
macos自带的/usr/libexec/java_home程序不识别sdkman安装的java,所以需要我们通过一些小 trick 来骗过macos,使得sdkman安装的java也能被系统识别到。为了增强文章阅读的趣味性,这篇文章我试着使用 ai 来润色和生成文本,今后我的博客也会更多的借助
aigc的力量,来辅助我讲清楚一些容易被我遗漏的知识细节,让后来的初学者也能更容易理解我的解决思路,并复现我的技术解决方案。
/Library/Java/JavaVirtualMachines高档小区,每户都有:
Contents/Home(真实住宅)Info.plist(房产证明)~/.sdkman的集装箱公寓,只有:
# 在苹果JDK小区买个虚拟房产
sudo mkdir -p /Library/Java/JavaVirtualMachines/sdkman-current/Contents
# 创建跨次元传送门(<YOUR_USERNAME>替换为你的用户名)
sudo ln -s /Users/<YOUR_USERNAME>/.sdkman/candidates/java/current \
/Library/Java/JavaVirtualMachines/sdkman-current/Contents/Home
<!-- 伪造Info.plist文件 -->
cat <<EOF | sudo tee /Library/Java/JavaVirtualMachines/sdkman-current/Contents/Info.plist
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleIdentifier</key>
<string>sdkman.current</string>
<key>CFBundleName</key>
<string>SDKMAN Current JDK</string>
<key>JavaVM</key>
<dict>
<key>JVMPlatformVersion</key>
<string>9999</string>
<key>JVMVendor</key>
<string>Homebrew</string>
<key>JVMVersion</key>
<string>9999</string>
</dict>
</dict>
</plist>
EOF
# 查看当前JDK路径
/usr/libexec/java_home
应该输出:
/Library/Java/JavaVirtualMachines/sdkman-current/Contents/Home
查看所有已识别JDK
/usr/libexec/java_home -V
输出示例:
Matching Java Virtual Machines (1):
9999 (arm64) "Homebrew" - "SDKMAN Current JDK" /Library/Java/JavaVirtualMachines/sdkman-current/Contents/Home
/Library/Java/JavaVirtualMachines/sdkman-current/Contents/Home
| 系统行为 | 我们的伪装术 |
|---|---|
| 扫描标准JDK目录 | 创建虚拟目录结构 |
| 检查Info.plist合法性 | 伪造包含必要字段的配置文件 |
| 验证JVM实际存在 | 符号链接指向真实SDKMAN路径 |
版本号9999的阴谋:通过设置超高版本号,确保系统总是优先选择我们的「超级JDK」
java_home依然装瞎三连诊断术
ls -l /Library/Java/JavaVirtualMachines/sdkman-current/Contents/Home # 检查传送门是否畅通
plutil -lint Info.plist # 验证身份证是否伪造成功
java -version # 确认SDKMAN当前JDK是否正常
# 总操作流程图
+------------------+ +------------------+ +------------------+
| 伪造JDK别墅 | | 创建传送门 | | 办理9999号身份证 |
| mkdir -p |------>| ln -s |------>| Info.plist |
+------------------+ +------------------+ +------------------+
为什么java_home这么固执?
就像机场安检员坚持要检查登机牌,java_home的设计哲学是:
# 在XCode中优雅调用(Build Phase脚本示例)
export JAVA_HOME=$(/usr/libexec/java_home)
./gradlew build --stacktrace # 现在可以愉快甩锅给Android Studio了