这个问题比较诡异,明明通过brew安装了11+的JDK,并且配置了环境变量,但Panoply就是不识别。

How

刚开始的解决方案:

brew install panoply

安装完成后会提示:

panoply requires Java 11+. You can install the latest version with:
brew install --cask temurin

然后将brew安装的OpenJDK卸载(如果你安装了的话)

brew uninstall --force --ignore-dependencies openjdk

OpenJDK可能被其他软件依赖,例如常用的Maven,默认依赖最新的OpenJDk,但是一般我们开发会额外安装1.8版本,所以系统上肯定有个能用的JDK,所以这里忽略依赖检查即可。

然后你就会发现,Panoply能用了。

Why

问题解决了,总要知道原因的,所以接下来分析一下什么原因导致的。

根据上面的操作,很容易想到是JDK版本冲突了。

可以通过下面的命令检查系统安装的JDK版本有哪些。

/usr/libexec/java_home -V

Matching Java Virtual Machines (3):

20.0.1 (x86_64) "Homebrew" - "OpenJDK 20.0.1" /usr/local/Cellar/openjdk/20.0.1/libexec/openjdk.jdk/Contents/Home
20.0.1 (x86_64) "Eclipse Adoptium" - "OpenJDK 20.0.1" /Library/Java/JavaVirtualMachines/temurin-20.jdk/Contents/Home
1.8.0_372 (x86_64) "Homebrew" - "OpenJDK 8" /usr/local/Cellar/openjdk@8/1.8.0+372/libexec/openjdk.jdk/Contents/Home

/usr/local/Cellar/openjdk/20.0.1/libexec/openjdk.jdk/Contents/Home

那么就有另外一个问题,我已经安装了OpenJDK 11+版本,为什么不能用?还要安装一个temurin?

软链接的问题?

抛开JDK内部可能不同的不谈,它们最明显的区别是,temurin文件直接安装在JavaVirtualMachines目录中,而brew安装的JDK是通过软链接的形式让系统识别。会不会是这个原因?实验一下就知道。

直接将brew安装OpenJDK复制到JavaVirtualMachines中,卸载temurin,删除软链接,,然后启动Panoply观察结果。

sudo cp -a -L /Library/Java/JavaVirtualMachines/openjdk.jdk /Library/Java/JavaVirtualMachines/openjdk2.jdk
sudo rm /Library/Java/JavaVirtualMachines/openjdk.jdk
brew uninstall temurin

实验失败,无法启动。

JDK的实现OR目录名称?

通过上面的验证,似乎问题和软链接无关。(这样得出的结论并不正确,应该将temurin变成软链接形式,再次测试,才能完全排除,后面也确认了确实和软链接有关)

再次猜想Panoly可能只认包名称,于是将刚刚复制的openjdk目录名称改成temurin安装的JDK相同。

sudo mv /Library/Java/JavaVirtualMachines/openjdk /Library/Java/JavaVirtualMachines/temurin-20.jdk

Yes!再次打开Panoply发现已经正常工作了。所以可以得出结论和JDK的实现无关。

经过反复验证,发现其实和前缀没有关系,而在于格式必须是*-version.jdk

brew安装最新的JDK并没有添加version后缀,所以识别不到。这里的version必须大于Panoply要求的11。

最终结论?

既和名称有关,也和软链接有关(我重新尝试在软连接的时候添加上版本号openjdk-20.jdk,发现还是无法工作)。

又尝试根据brew的提示将JDK软链接到JavaVirtualMachines,然后复制一份带版本后缀的副本,也是无法工作。

所以结论就是:

Panoply会根据名称里的版本后缀,寻找版本号最大的一个JDK,然后使用它。并且这个目录必须是实实在在的目录,不是软链接。因为默认的OpenJDK和temurin版本号都是20,Panoply根据temurin的后缀得知系统安装的JDK最新版本为20,然后通过/usr/libexec/java_home -v 20获取JDK路径,结果获取到的是OpenJDK的路径,而它是个软链接,软链接又不支持……

最终选择

为了避免手动复制文件的麻烦,我仍然选择安装temurin,然后取消将OpenJDK软链接到JavaVirtualMachines下,20版本使用temurin提供的就好了。

到头来其实和一开始的方案一样,OpenJDK卸不卸载都行。

最后修改:2023 年 08 月 02 日
如果觉得我的文章对你有用,请随意赞赏