なぜ誤認させたい?
- SDKMANをセットアップすると
JAVA_HOME
をSDKMANがよしなにしてくれるようなる -
/usr/bin/java
,/usr/libexec/java_home
などが変わらずSystem JDKの場所である/Library/Java/JavaVirtualMachines
配下のJDKを参照する - XcodeのScriptPhaseなどJAVA_HOMEを見ず、強制的にSystem JDKを参照するライブラリやプラグイン類がいる
- どうにかしてPCにinstallするJDKをSDKMANだけに寄せたいのでSDKMANでinstallしたJDKをSystem JDKに誤認させたい
SDKMAN以外のJDKはどうなっているか
- システムのJDKは
/Library/Java/JavaVirtualMachines
にinstallもしくはsymbolic linkを貼ったものであるパターンが多い-
jdk.java.netからinstallする場合、tarファイルを
/Library/Java/JavaVirtualMachines
に展開する - Homebrewでopenjdkをinstallする場合、システムが認識できるようにシンボリックリンクを貼るように表示される
-
For the system Java wrappers to find this JDK, symlink it with sudo ln -sfn /opt/homebrew/opt/openjdk/libexec/openjdk.jdk /Library/Java/JavaVirtualMachines/openjdk.jdk openjdk is keg-only, which means it was not symlinked into /opt/homebrew, because macOS provides similar software and installing this software in parallel can cause all kinds of trouble. If you need to have openjdk first in your PATH, run: echo 'export PATH="/opt/homebrew/opt/openjdk/bin:$PATH"' >> $HOME.zshrc For compilers to find openjdk you may need to set: export CPPFLAGS="-I/opt/homebrew/opt/openjdk/include"
-
jdk.java.netからinstallする場合、tarファイルを
-
/Library/Java/JavaVirtualMachines
にApplication Bundle形式でJDKが展開される- Distributionによって若干の差異はあるが以下のようなファイル構造になる
-
/Library/Java/JavaVirtualMachines └── Contents ├── CodeResources ├── Home │ ├── bin │ ├── conf │ ├── include │ ├── jmods │ ├── legal │ ├── lib │ └── release ├── Info.plist ├── MacOS │ └── libjli.dylib └── _CodeSignature └── CodeResources
-
- Distributionによって若干の差異はあるが以下のようなファイル構造になる
SDKMANでinstallしたJDKはどうなっているか
- 特別なinstall設定を行わない場合
$HOME/.sdkman/candidates/java
配下にinstallされる - Distributionによって若干の差異はあるが、以下のようなファイル構造になる
- 概ねApplication Bundle形式のHomeディレクトリの内容だと考えていい
$HOME/.sdkman/candidates/java
└──17.0.13-tem
├── NOTICE
├── bin
├── conf
├── include
├── jmods
├── legal
├── lib
├── man
└── release
System JDKとして認識されるためにはどうすればよいか
- OpenJDKを参考にすると
/Library/Java/JavaVirtualMachines/Contents
配下にsymbolic linkとファイルを配置する必要がある- bin, conf各種がある
Home
-
libjli.dylib
があるMacOS
-
Info.plist
の作成
- bin, conf各種がある
Home
,MacOS
ディレクトリへのsymbolic link作成
- SDKMANでinstallしたJDKのsymbolic linkを作成してあげればよい
# directoryの作成(sdkman.jdkは任意の名前)
sudo mkdir -p /Library/Java/JavaVirtualMachines/sdkman.jdk/Contents/Home
sudo mkdir -p /Library/Java/JavaVirtualMachines/sdkman.jdk/Contents/MacOS
# bin, conf, include, jmods, legal, lib系のsymbolic link作成
sudo ln -sfn ~/.sdkman/candidates/java/17.0.13-tem/* /Library/Java/JavaVirtualMachines/sdkman.jdk/Contents/Home
# libjli.dylibの位置ははDistributionによって異なるので注意する必要がある(↓はtemurinの場合)
sudo ln -sfn ~/.sdkman/candidates/java/17.0.13-tem/lib/libjli.dylib /Library/Java/JavaVirtualMachines/sdkman.jdk/Contents/MacOS/libjli.dylib
Info.plist
の作成
- Homebrewでopenjdkをinstallした際は
/opt/homebrew/Cellar/openjdk/23/libexec/openjdk.jdk/Contents
に以下のInfo.plistが配置されている
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>CFBundleDevelopmentRegion</key>
<string>English</string>
<key>CFBundleExecutable</key>
<string>libjli.dylib</string>
<key>CFBundleGetInfoString</key>
<string>OpenJDK 23</string>
<key>CFBundleIdentifier</key>
<string>net.java.openjdk.jdk</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>7.0</string>
<key>CFBundleName</key>
<string>OpenJDK 23</string>
<key>CFBundlePackageType</key>
<string>BNDL</string>
<key>CFBundleShortVersionString</key>
<string>23</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>0</string>
<key>NSMicrophoneUsageDescription</key>
<string>The application is requesting access to the microphone.</string>
<key>JavaVM</key>
<dict>
<key>JVMCapabilities</key>
<array>
<string>CommandLine</string>
</array>
<key>JVMMinimumFrameworkVersion</key>
<string>13.2.9</string>
<key>JVMMinimumSystemVersion</key>
<string>11.00.00</string>
<key>JVMPlatformVersion</key>
<string>23</string>
<key>JVMVendor</key>
<string>Homebrew</string>
<key>JVMVersion</key>
<string>23</string>
</dict>
</dict>
</plist>
- Systemが最低限認識できるようにすると以下のようなInfo.plistになる
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.jdk</string>
<key>CFBundleName</key>
<string>SDKMAN current JDK</string>
<key>CFBundleExecutable</key>
<string>libjli.dylib</string>
<key>JavaVM</key>
<dict>
<key>JVMCapabilities</key>
<array>
<string>CommandLine</string>
</array>
<key>JVMPlatformVersion</key>
<string>${sdk current java}</string>
<key>JVMVendor</key>
<string>SDKMAN</string>
<key>JVMVersion</key>
<string>${sdk current java}</string>
</dict>
</dict>
</plist>
要素さえ揃っていれば、CFBundleIdentifier
, CFBundleName
, JavaVM
は任意の値で問題ない
結果
- ここまで実施すると
/usr/bin/java
,/usr/libexec/java_home
がSDKMANでinstallしたJDKをSystem JDKとして認譋するようになる
$ where java
/usr/bin/java
$HOME/.sdkman/candidates/java/current/bin/java
$ /usr/bin/java -version
openjdk version "17.0.13" 2024-10-15
OpenJDK Runtime Environment Temurin-17.0.13+11 (build 17.0.13+11)
OpenJDK 64-Bit Server VM Temurin-17.0.13+11 (build 17.0.13+11, mixed mode, sharing)
$ /usr/libexec/java_home -V
Matching Java Virtual Machines (1):
${sdk current java} (arm64) "SDKMAN" - "SDKMAN current JDK" /Library/Java/JavaVirtualMachines/sdkman.jdk/Contents/Home
/Library/Java/JavaVirtualMachines/sdkman.jdk/Contents/Home
Ref