如何在启动前检查 JRE 版本?
确定计算机上安装的 JRE 版本对于用户想要运行的应用程序是否足够高的最佳方法是什么? 有没有办法使用纯java的东西来做到这一点? 我希望该解决方案能够在 Windows/Linux/MacOSX 上运行 - 如果 JRE 版本太低,则应显示一条消息。 目前,如果我尝试在 Java 1.5 上运行它(该应用程序是为 Java 1.6 构建的),我会遇到异常。 如果没有通用的解决方案,那么在 Windows 上执行此操作的最佳方法是什么?
What's the best way to determine if the version of the JRE installed on a machine is high enough for the application which the user wants to run? Is there a way of doing it using java-only stuff? I'd like the solution to work on Windows/Linux/MacOSX - if the JRE version is too low a message should be displayed. Currently I'm getting an exception if i try to run it on Java 1.5 (the app is built for Java 1.6). If there's no universal solution, what's the best way to do it on Windows?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(13)
您可以使用反射和两个编译器来完成此操作。 使用您希望能够运行的最旧的 java 版本编译主类。 它使用 System.getProperty("java.version") 或其他方式检查版本,然后使用反射来加载您的真实主类(如果检查通过),甚至可能直接加载jar。 JRE 不应加载编译时外部主类未引用的任何类。
You could do this using reflection and two compilers. Compile a main class with the oldest java version you want to be able to run at all with. It checks the version using
System.getProperty("java.version")
, or whatever, and then uses reflection to load your real main class if that check passes, possibly even loading the jar directly. The JRE shouldn't load any classes that weren't referenced by your outer main class at compile time.您可能会考虑Java Webstart。 即使名称暗示类似小程序的东西,它也是关于独立应用程序的。 Webstart 是一个启动器,它检查 JNLP 文件(一个简单的 XML 文件,您可以在其中配置应用程序的下载位置、所需的 Java 版本和一些其他元数据)并使用正确的 JRE 启动您的应用程序。 如果有新版本可用,它甚至会更新应用程序。 缺点是,您必须编写 JNLP 文件。 这是一个示例:
第二种可能性是使用启动程序。 一个示例是 Apache Commons Launcher。 您也可以自己编写一些启动器应用程序,但这通常不值得付出努力。
You might consider Java Webstart. Even if the name implies something like applets, it's about standalone-applications. Webstart is a launcher, that checks a JNLP-file (a simple XML-file, where you configure the download-location of your app, the needed Java-version and some other metadata) and starts your app with the correct JRE. It even updates the application, if a newer version is available. The downside is, you have to write a JNLP-file. Here is an example:
A second possibility is to use a launcher-program. An example is the Apache Commons Launcher. You can also write some launcher app yourself, but that's usually not worth the effort.
您还可以考虑使用 Commons-Launcher,它允许您设置各种环境设置,或在调用应用程序之前执行预检查。
http://commons.apache.org/launcher
You might also consider using Commons-Launcher, which allows you to setup various environment settings, or perform pre-checks before calling your application.
http://commons.apache.org/launcher
一般来说,我们使用 C 或(仅适用于 UNIX 时)shell 包装器来解决这个问题。 不确定这是否真的适合你。
我们还通过在我们的产品中嵌入 JRE 来解决这个问题。 处理 99.9% 的情况(另外 0.1% 的情况是用户明确更改我们的配置以使用不同的 JVM)。 再次强调,不确定这对您来说是否是一个合理的解决方案。
在我们的例子中,有大量的本机代码(JNI 和其他代码),因此无论如何都需要为我们支持的每个平台定制可安装的映像。 但是,如果您正在处理纯 Java 解决方案,您可能只需记录您的最低要求,并告诉人们如果要运行您的东西就使用该程序(没有双关语)。 这有点像人们抱怨我的 Mac 无法运行 MSVC,或者我的 Linux 机器在运行《魔兽世界》时出现问题。 这不是软件所针对的(虚拟)机器 - 您需要进行切换。 不过,至少在 Java 世界中,我们确实可以将其称为升级,而不会伤害任何人的操作系统宗教感情。 (尝试告诉 Mac 用户“升级”到 Windows XP 以运行 MSVC - 等待发生的将会是一场惨败。)
Generally, we've approached this with a C or (when unix-only) shell wrapper. Not sure this will really work for you.
We also approach this by embedding the JRE in our product. Takes care of 99.9% of the cases (the other 0.1% of the time is a user explicitly changing our configuration to use a different JVM). Again, not sure that this is a reasonable solution for you.
In our case, there is significant amounts of native code (JNI and otherwise), so tailoring an installable image for each platform we support is required anyway. But if you're dealing with a pure-Java solution, you may simply have to document your minimum and tell people to get with the program (no pun intended) if they're to run your stuff. It's sorta like people complaining that my Mac won't run MSVC, or that my Linux box is having problems running World of Warcraft. That's just not the (virtual) machine the software is targeted for - you need to switch. At least in the Java world, we really can call this an upgrade, though, without hurting anyone's OS-religious feelings. (Try telling the Mac user to "upgrade" to Windows XP to run MSVC - there's a beat-down waiting to happen.)
运行 Java 命令时,您可以要求 Java 版本,例如
java -version:1.6* com.me.MyClass
。 不确定这是否适用于所有 Java 版本,但无论如何在 1.6 上都可以正常工作。You can require a Java version when running the Java command, e.g.
java -version:1.6* com.me.MyClass
. Not sure if this works on all releases of Java, but it works OK on 1.6 anyway.为较高版本的 JRE 构建的应用程序将无法在较低版本的 JRE 上运行。 因此,您无法仅向应用程序添加代码来检查 JRE 版本 - 如果 JRE 版本不兼容,您的 JRE 版本检查代码将不会首先运行。
您需要做的是拥有某种为较低版本的 JRE(1.3?)构建的启动器应用程序,它会检查版本,然后在必要时启动您的应用程序。 这对我来说听起来有点笨拙。
安装时检查版本怎么样? 您安装应用程序的方式是否允许您检查环境变量或执行任何类型的脚本?
An application built for a higher-version JRE will not run on a lower-version JRE. So you wouldn't be able to just add code to your application to check the JRE version - if the JRE version was incompatible, your JRE-version-checking code would not run in the first place.
What you'd have to do is have some sort of launcher application that is built for a lower-version JRE (1.3?) that checks the version and then launches your app if necessary. This sounds kind of kludgy to me.
What about checking the version during installation? Are you installing the app in a way that allows you to check environment variables, or do any sort of scripting?
对于启动器 - 检查其中的版本。
APP内; 如上所述使用 System.getProperties();
For the launcher - Check the version in there.
Inside the APP; as above use System.getProperties();
为 Java 1.2 编译一个启动类,它调用 1.6 类中的 real main()。 如果抛出不支持的类异常,它们会捕获它并显示一条不错的错误消息。
Have a launching class compiled for Java 1.2 which invokes the real main() in your 1.6 classes. If an unsupported class exception is thrown them catch it and display a nice error message.
以下是获取系统中安装的 JRE 版本的代码。
Here is the code to get the JRE version installed in a system.
System.getProperties() 为您提供 JVM 属性列表,包括 JRE、JVM 和规范的不同版本 ID。 这适用于所有版本的 Java,因此无论编译版本和运行版本或实现如何,都应该有效。
如果您编写一个基本类来测试版本,则可以首先在 main() 启动类中调用它。 但它必须确实是基本功能,否则您可能会冒破坏它的风险。
System.getProperties() gives you a listing of JVM properties including the different version ids of the JRE, JVM and specification. This implemented for all versions of Java so should work regardless of version compiled in and version run in, or the implementation.
If you write a basic class to test the version, you can call this first in your main() launching class. It must really be basic functionality though or you might risk breaking it.
嗯..称我为无聊的家伙,但是使用 Launch4J 或任何其他本机启动器有什么问题呢?
在实际运行代码之前,使用本机启动器检查 JVM 版本。 仅 Java 解决方案(在我的书中)只有在与开发人员打交道时才有意义; 一旦接触到最终用户,您就会意识到他们根本不关心 Java 或其技术细节。 如果您使用 GW-Basic 编写应用程序,只要您的应用程序有效,他们就不会关心。
如果未安装 Java 1.6,lauchner4j 会将用户引导至 JDK 1.6 的下载页面。 这可能比用 Java 做魔术更适合你的问题。
Hmm .. call me a boring guy, but what's wrong with using Launch4J or any other native launcher, for instance.
Use a native launcher to check the JVM version before actually running your code. Java only solutions (in my book) only make sense when you deal with developers; once you hit end-users, you'll realize that they dont care about Java or its technical details at all. If you would have written your application in GW-Basic they would not care less as long as your application works.
If Java 1.6 is not installed, lauchner4j will point the user to the download page for JDK 1.6. Thats probably more suitable for your problem than doing magic in Java.
我发现 WinRun4J 对我来说效果很好(但话又说回来,我可能有偏见,因为我写的:-))。 这允许您指定允许的最小和/或最大 java 版本。 如果没有找到合适的 JRE 版本,它将向用户弹出一个消息框(并且该消息是可自定义的)。
I find that WinRun4J works quite well for me (but then again I may be biased since I wrote it:-)). This lets you specify a minimum and/or maximum version of java allowed. It will pop up a message box to the user if a suitable JRE version is not found (and the message is customisable).
以上这些都太复杂了。
只要走:
您就会看到有关 JVM、JRE、JDK 和员工的所有信息。
或者使用以下方法获取特定值:
All those above is too damn complicated.
Just go:
And you will see everything about your JVM, JRE, JDK and staff.
Or get a specific value by using: