许多第三方产品需要特定版本的 JRE 或 JDK,而且我们的许多服务器都有多种职责。应用程序团队认为他们不应该关心 Java 的安装位置。大多数应用程序仅依赖于环境变量(或任何 Java 碰巧存在),但需要告知那些需要特定版本的团队在哪里可以找到他们的特定版本。我不喜欢在不访问所有可能使用它的应用程序的情况下无法重新定位 JVM 的事实。显而易见的答案是创建一个程序来隐藏细节并通过 API 公开位置。该解决方案要求每个 Java 应用程序都包含在一些查询环境的脚本中。
我不喜欢不必要的复杂性或重新发明轮子。是否有一些标准做法、Java 内置功能或我缺少的明显解决方案?
我想到的一个方法是让每个应用程序在其路径中管理一个链接以指向它想要的 Java,但我仍然需要告诉他们它在哪里。
虚拟化是我们在我工作的地方处理它的方式。
更新 - 抱歉,如果我不清楚 - 我们将每个应用程序托管在自己的虚拟服务器上,只有它需要的 JVM 版本
理想情况下,您需要设置两个环境变量:
您可以创建不同的脚本来启动各种程序,并在每种情况下以不同的方式设置这些变量。或者,您可以将每个应用程序配置为在不同的用户帐户下启动,并在用户相应的启动脚本中设置这些变量。
$JAVA_HOME/bin 需要首先出现在 PATH 中,以避免运行默认路径上的任何其他 java 二进制文件。
符号链接方法很好,但考虑到您可能不想一次升级所有应用程序的 jvm。
如果您正在处理任务关键型应用程序,那么您可能希望每个应用程序有一个 JVM,或者让每个应用程序直接指向特定版本的 JVM。
例如,在我工作的地方,有一个应用程序(称为 A)专门工作并针对特定的 JDK 和版本(JDK 1.5.0_03)进行了测试,已知更高版本会破坏它。
如果应用程序 A 和另一个应用程序 B 都指向一个名为 java-5 的符号链接,然后在推出应用程序 BI 时决定更新 java-5 以指向 JDK 1.5.0_14,那么应用程序 A 将中断。
正如“在版本控制下处理系统特定信息的最佳实践是什么?”中提到的,JVM 的路径可以是去变量化阶段的一部分。
即您的配置文件可以在以下位置重写:
这意味着,就在应用程序的开头,我们在所有程序中放入了对数据库的查询,其中包含可能在会话之间更改的值。
最终的 JVM 路径就是其中之一。
查询基于服务器(或服务器池)名称和程序名称。
在基于 *nix 的系统中,您可以使用软链接。然后只需编写启动脚本以使用它喜欢的最不具体的版本。JRE_HOME = /usr/lib/jre/java-5
这是许多基于 Linux 的系统使用的方法。有关示例,请参见 /etc/alternitives 和 /usr/lib/jre。
在 Windows 中,您可以使用环境变量来做类似的事情。然后您的启动脚本可以“设置 JRE_HOME=%JAVA_5%”。
应用程序团队不能同时拥有它。
如果应用程序只支持一个版本的 JRE,那么它应该附带它。它应该与应用程序一起安装。
我不明白为什么他们会以其他方式想要它。这样做可以确保他们测试应用程序所用的确切 JRE 版本与您在生产中部署的版本相同。当你在学校时认为你应该“不关心”JVM是一个很好的理想,而Java是“一次编写,在任何地方运行”。但坦率地说,这种观点与现实世界并不相符,Java 实际上是“一次编写,到处测试”。
对于应用程序团队来说,必须关心特定于 JVM 的问题将是一场噩梦。消除这种不确定性,吸收它并为每个应用程序使用一个 JVM。磁盘空间很便宜。
我们只是使用符号链接到我们想要使用的版本。我们有许多机器在不同的位置安装了java,应用程序不需要知道它们在不同的盒子上的位置。
另一种选择是为您的应用程序使用 java webstart。在这种情况下,如果您没有它,它甚至会下载并安装正确的版本。
我使用从 Sun 提取的下载文件将所有内容放在 /opt/java-version 中(保留默认目录名称)。应用程序通常以自己的用户身份运行,并通过一个初始化脚本启动和停止,该脚本设置该应用程序的所有变量,包括 $JAVA_HOME。
如果我有一个应用程序,我希望始终在 /opt 中使用“当前”安装,我会在 /opt 中创建符号链接并使 init 脚本指向该符号链接。然后在安装新的 Java 运行时调整符号链接。