如何在发布之前检查JRE版本?

时间:2008-10-21 14:54:59

标签: version java launch

确定计算机上安装的JRE版本是否足以满足用户想要运行的应用程序的最佳方法是什么?有没有办法使用java-only的东西呢?我希望该解决方案适用于Windows / Linux / MacOSX - 如果JRE版本太低,则应显示消息。目前,如果我尝试在Java 1.5上运行它(该应用程序是为Java 1.6构建的),我会遇到异常。如果没有通用解决方案,那么在Windows上执行此操作的最佳方式是什么?

13 个答案:

答案 0 :(得分:11)

你可以使用反射和两个编译器来做到这一点。使用您希望能够运行的最旧的Java版本编译主类。它使用System.getProperty("java.version")或其他任何方式检查版本,然后使用反射加载真实的主类,如果该检查通过,甚至可能直接加载jar。 JRE不应加载在编译时未被外部主类引用的任何类。

答案 1 :(得分:9)

您可以考虑Java Webstart。即使名称暗示类似于applet,它也是关于独立应用程序的。 Webstart是一个启动程序,用于检查JNLP文件(一个简单的XML文件,您可以在其中配置应用程序的下载位置,所需的Java版本和其他一些元数据)并使用正确的JRE启动您的应用程序。如果有更新版本,它甚至会更新应用程序。缺点是,你必须写一个JNLP文件。这是一个例子:

<?xml version="1.0" encoding="utf-8"?>

<!--
###############################################################################
#
# @(#)draw.jnlp 1.6 02/09/11
#
# JNLP File for Draw Demo Application
#
###############################################################################
 -->


<jnlp spec="0.2 1.0"
      codebase="http://java.sun.com/javase/technologies/desktop/javawebstart/apps"
      href="draw.jnlp">
   <information> 
      <title>Draw 4 App</title> 
      <vendor>Sun Microsystems, Inc.</vendor>
      <homepage href="http://java.sun.com/javase/technologies/desktop/javawebstart/demos.html"/>
      <description>A minimalist drawing application along the lines of Illustrator</description>
      <description kind="short">Draw Demo Short Description</description>
      <icon href="images/draw.jpg"/>
      <offline-allowed/> 
   </information> 
   <resources>
      <j2se version="1.3+" href="http://java.sun.com/products/autodl/j2se"/>
      <j2se version="1.3+"/>
      <jar href="draw.jar" main="true" download="eager"/>
   </resources>
   <application-desc main-class="Draw"/>
</jnlp> 

第二种可能性是使用启动程序。一个例子是Apache Commons Launcher。您也可以自己编写一些启动器应用程序,但这通常不值得。

答案 2 :(得分:5)

您也可以考虑使用Commons-Launcher,它允许您设置各种环境设置,或在调用您的应用程序之前执行预检查。

http://commons.apache.org/launcher

答案 3 :(得分:2)

通常,我们使用C或(仅限unix)shell包装器来处理此问题。不确定这对你有用。

我们也通过将JRE嵌入到我们的产品中来解决这个问题。处理99.9%的情况(另外0.1%的情况是用户明确地将我们的配置更改为使用不同的JVM)。同样,不确定这是否是一个合理的解决方案。

在我们的案例中,有大量的本机代码(JNI和其他),因此无论如何都需要为我们支持的每个平台定制可安装的映像。但是,如果你正在处理一个纯Java解决方案,你可能只需要记录你的最低要求并告诉人们如果他们要运行你的东西,就可以使用该程序(没有双关语)。这有点像人们抱怨我的Mac不会运行MSVC,或者我的Linux机器在运行魔兽世界时遇到问题。这不是软件所针对的(虚拟)机器 - 您需要切换。至少在Java世界中,我们真的可以称之为升级,但不会伤害任何人的操作系统宗教感受。 (尝试告诉Mac用户“升级”到Windows XP以运行MSVC - 有一个节奏等待发生。)

答案 4 :(得分:2)

运行Java命令时可以要求Java版本,例如: java -version:1.6* com.me.MyClass。不确定这是否适用于所有Java版本,但无论如何它在1.6上都可以正常工作。

答案 5 :(得分:1)

为更高版本的JRE构建的应用程序不能在较低版本的JRE上运行。因此,您无法仅将代码添加到应用程序以检查JRE版本 - 如果JRE版本不兼容,则JRE版本检查代码将不会首先运行。

你需要做的是有一些为较低版本的JRE(1.3?)构建的启动器应用程序,它会检查版本,然后在必要时启动你的应用程序。这对我来说听起来很糟糕。

安装期间检查版本怎么样?您是否以允许检查环境变量或执行任何脚本编写的方式安装应用程序?

答案 6 :(得分:1)

对于启动器 - 检查那里的版本。

APP内部;如上所述使用System.getProperties();

Properties sProp = java.lang.System.getProperties();
String sVersion = sProp.getProperty("java.version");
sVersion = sVersion.substring(0, 3);
Float f = Float.valueOf(sVersion);
if (f.floatValue() < (float) 1.4) {
    System.out.println("Java version too low ....");
    System.exit(1);
}
...

答案 7 :(得分:1)

为Java 1.2编译一个启动类,它在1.6类中调用 real main()。如果抛出不受支持的类异常,则捕获它并显示一条漂亮的错误消息。

答案 8 :(得分:1)

以下是在系统中安装JRE版本的代码。

var list = deployJava.getJREs();
var result = "";
result = list[0];
for (var i=1; i<list.length; i++)
{
    result += ", " + list[i];
} 
document.write("jre version : "+result);

答案 9 :(得分:0)

System.getProperties()为您提供了JVM属性的列表,包括JRE,JVM和规范的不同版本ID。这适用于所有版本的Java,因此无论编译版本和版本运行版本,还是实现版本都应该有效。

如果您编写基本类来测试版本,可以先在main()启动类中调用它。它必须真的是基本的功能,否则你可能会冒险破坏它。

答案 10 :(得分:0)

嗯..叫我一个无聊的家伙,但是使用Launch4J或任何其他原生发射器有什么问题。

在实际运行代码之前,使用本机启动程序检查JVM版本。只有Java的解决方案(在我的书中)只有在与开发人员打交道时才有意义;一旦你遇到了最终用户,你就会意识到他们根本不关心Java或其技术细节。如果您已经在GW-Basic中编写了应用程序,只要您的应用程序正常运行,他们就不会在意。

如果未安装Java 1.6,lauchner4j会将用户指向JDK 1.6的下载页面。这可能比在Java中做魔术更适合你的问题。

答案 11 :(得分:0)

我发现WinRun4J对我来说效果很好(但是自从我写这篇文章后,我可能会有所偏见:-))。这允许您指定允许的最小和/或最大版本的java。如果找不到合适的JRE版本(并且消息可自定义),它将向用户弹出一个消息框。

答案 12 :(得分:0)

以上所有这些都太复杂了。 去吧:

Properties props = System.getProperties()
props.list(System.out)

您将看到有关JVM,JRE,JDK和员工的所有信息。 或者使用以下方法获取特定值:

//full list of possible props you can see if u run code above
String props = System.getProperty(prop)