macOS(Big Sur):eclipse下引用JDK 8 tools.jar 塈在macOS下为eclipse设置JAVA_HOME环境变量问题

以下为我的项目中关于引用JDK下tools.jar的pom.xml片段,在windows,Linux下都工作正常,最近换到MacOS 11(Big Sur)下工作,命令行执行编译没有问题,但在eclipse(最新版本eclipse-java-2021-03-R-macosx-cocoa-x86_64.dmg)发现它不正常了。

	<profiles>
		<profile>
			<id>default-javadoc-profile</id>
			<activation>
				<activeByDefault>true</activeByDefault>
				<file>
					<exists>${java.home}/../lib/tools.jar</exists>
				</file>
			</activation>
			<properties>
				<toolsjar>${java.home}/../lib/tools.jar</toolsjar>
			</properties>
		</profile>
	</profiles>

直接的原因就是找不到${java.home}/lib/tools.jar定义的文件,显然是${java.home}有问题。eclipse下maven中${java.home}内置属性是eclipse应用程序运行所使用的JVM所在的位置.打开eclipse.ini

cat /Applications/Eclipse.app/Contents/Eclipse/eclipse.ini

如下图可以看到安装eclipse时默认使用的是JRE 11而不是JDK,JRE中没有tools.jar所以就报错喽
在这里插入图片描述
怎么解决呢?

Eclipse使用本地JDK(放弃)

修改/Applications/Eclipse.app/Contents/Eclipse/eclipse.ini让eclipse使用我电脑上安装的JDK 8做JVM,如下修改-vm参数的值

-vm
/usr/bin

关于修改eclipse的JVM,参见 eclipse官方说明:https://wiki.eclipse.org/Eclipse.ini

然而这个方法是有代价的,因为我用的eclipse要求JRE 11版本,所以不能使用本地的JDK 8做JVM。

使用JDK8的eclipse

重新安装使用JDK8的eclipse 旧版本是一个解决办法,但降低版本对于最新的macOS 11 Big Sur系统会不会有兼容性问题也不可知,但我觉得太麻烦,不到万不得已不会使用这个方案。

本地JDK升级到11

升级本地的JDK版本到11,然后使用上述方法修改eclipse.ini也是可以的,但对于我并不合适,因为我的项目都是基于JDK 7或8的,突然因此被迫升级JDK版本后面有多少麻烦也不可知。

所以我反复权衡没有采用这两个办法。

使用${evn.JAVA_HOME}代替${java.home}

既然 ${java.home}不可使用,使用 ${evn.JAVA_HOME}这个环境变量总是可以的。它是不受eclipse应用程序影响的。

于是我把pom.xml做了如下修改,增一个针对macOS的profile

		<profile>
			<id>osx-javadoc-profile</id>
			<activation>
				<os>
					<family>mac</family>
				</os>
			</activation>
			<properties>
				<toolsjar>${env.JAVA_HOME}/lib/tools.jar</toolsjar>
			</properties>
		</profile>

这次的问题是找不到${env.JAVA_HOME}环境变量。

事实上我确实在.zprofile中已经添加了JAVA_HOME定义。按道理不应该呀。为什么?对于我这个macOS的手新来说太不可理解了。

macOS 10以后默认的脚本解释器是zsh,不再是bash,所以这里不是修改.bash_profile

在google上一通找,下面这两篇文章让我基本搞明白了原因:

《Setting environment variables on OS X》
《Setting environment variables in OS X for GUI applications》

macOS平台下对于像eclipse这样的非命令行的应用程序(GUI application),运行时是不会从.zprofile,.zshrc或.bash_profile,.bashrc读取环境变量的。如果要为应用程序设置环境就需要通过launchctrl setenv key value方式来完成。
以设置 JAVA_HOME 为例

launchctl setenv JAVA_HOME=$(/usr/libexec/java_home)

在/etc/launchd.conf 添加 setenv JAVA_HOME=$(/usr/libexec/java_home)的方式在Mac OS X 10.10 and higher版本已经不再支持参见:
《HowTo: Set an Environment Variable in Mac OS X - /etc/launchd.conf》

launchctrl setenv key value方式只是设置环境变量并不能持久化,电脑重启就失效了。如何写配置文件让它持久化呢?

如何持久化1:.zshenv

.zshenv 是ZSH的环境变量设置文件,非交互式应用程序每次启动都会读取,将JAVA_HOME在这里设置,eclipse等应用程序就可以正确获取。

echo "launchctl setenv JAVA_HOME=$(/usr/libexec/java_home)" > ~/.zshenv

显然该方法只对当前用户有效

如何持久化2:launchd.plist

下面这篇文章介绍了如何基于launchd.plist设置应用程序的环境变量

《HowTo: Set an Environment Variable in Mac OS X - launchd.plist》

具体做法还以JAVA_HOME为例:

/Library/LaunchDaemons下创建setenv.JAVA_HOME.plist文件(文件名字随便你定义,后缀要为.plist)

# 需要管理员权限
sudo touch /Library/LaunchDaemons/setenv.JAVA_HOME.plist 

修改setenv.JAVA_HOME.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>Label</key>
  <string>setenv.JAVA_HOME</string>
  <key>ProgramArguments</key>
  <array>
    <string>/bin/launchctl</string>
    <string>setenv</string>
    <string>JAVA_HOME</string>
    <!-- your JDK path  -->
    <string>/Library/Java/JavaVirtualMachines/jdk1.8.0_281.jdk/Contents/Home</string>
  </array>
  <key>RunAtLoad</key>
  <true/>
  <key>ServiceIPC</key>
  <false/>
</dict>
</plist>

保存文件后重启电脑,则一切正常。
此方法是在系统中增加了环境变量设置,对电脑上的所有用户有效。

参考资料

《Setting environment variables on OS X》

《Setting environment variables in OS X for GUI applications》

《-vm value: macOS Example》

《HowTo: Set an Environment Variable in Mac OS X - /etc/launchd.conf》

《HowTo: Set an Environment Variable in Mac OS X - launchd.plist》

《What should/shouldn’t go in .zshenv, .zshrc, .zlogin, .zprofile, .zlogout?》

《ZSH: .zprofile, .zshrc, .zlogin - What goes where?》

おすすめ

転載: blog.csdn.net/10km/article/details/115758401