如何在没有安装JDK的不同计算机上运行jar文件?

huangapple go评论62阅读模式
英文:

How to run jar on different computer without JDK?

问题

I created Java application and built a jar file. I can run this jar on my computer, but when I try to run it on other computer (with no JDK installed) by double click on jar, I'm getting an error:
在我的电脑上,我创建了一个Java应用程序并构建了一个jar文件。但是,当我尝试在另一台没有安装JDK的计算机上双击运行jar文件时,出现了错误:

A Java Exception has occured.
出现了Java异常。

When I run it from command line using java -jar <filename.jar>, I'm getting such error:
当我在命令行中使用 java -jar <filename.jar> 运行它时,出现如下错误:

Exception in thread "main" java.lang.UnsupportedClassVersionError: MainWindow has been compiled by a more recent version of the Java Runtime (class file version 62.0), this version of the Java Runtime only recognizes class file versions up to 52.0
在线程 "main" 中发生异常,java.lang.UnsupportedClassVersionError:MainWindow已由Java Runtime的更高版本编译(类文件版本62.0),这个Java Runtime版本仅支持类文件版本最高到52.0

I checked Java versions on both computers.
我检查了两台计算机上的Java版本。

First computer (with JDK):
第一台计算机(安装了JDK):
java version "18.0.2" 2022-07-19
Java(TM) SE Runtime Environment (build 18.0.2+9-61)
Java HotSpot(TM) 64-Bit Server VM (build 18.0.2+9-61, mixed mode, sharing)

Second computer (without JDK):
第二台计算机(没有安装JDK):
java version "1.8.0_361"
Java(TM) SE Runtime Environment (build 1.8.0_361-b09)
Java HotSpot(TM) Client VM (build 25.361-b09, mixed mode, sharing)

As I know, it should be possible to run a Jar file without JDK installed, just JRE should be enough. But it looks like this JRE is too old version? (I don't think so, but maybe I'm wrong.)
据我所知,应该可以在没有安装JDK的情况下运行Jar文件,只需安装JRE就足够了。但似乎这个JRE版本太旧?(我不这样认为,但也许我错了。)

Summary:
总结:
How to run a jar on the second computer without installing JDK?
如何在第二台计算机上运行一个jar文件,而不安装JDK?

英文:

I created Java application and built a jar file. I can run this jar on my computer, but when I try to run it on other computer (with no JDK installed) by double click on jar, I'm getting an error:
A Java Exception has occured.

When I run it from command line using java -jar &lt;filename.jar&gt;, I'm getting such error:
> Exception in thread "main" java.lang.UnsupportedClassVersionError: MainWindow has been compiled by a more recent version of the Java Runtime (class file version 62.0), this version of the Java Runtime only recognizes class file versions up to 52.0

I checked Java versions on both computers.

First computer (with JDK):<br>
java version "18.0.2" 2022-07-19<br>
Java(TM) SE Runtime Environment (build 18.0.2+9-61)<br>
Java HotSpot(TM) 64-Bit Server VM (build 18.0.2+9-61, mixed mode, sharing)

Second computer (without JDK):<br>
java version "1.8.0_361"<br>
Java(TM) SE Runtime Environment (build 1.8.0_361-b09)<br>
Java HotSpot(TM) Client VM (build 25.361-b09, mixed mode, sharing)

As I know, it should be possible to run a Jar file without JDK installed, just JRE should be enough. But it looks like this JRE is too old version? (I don't think so, but maybe I'm wrong.)

Summary:<br>
How to run a jar on the second computer without installing JDK?

答案1

得分: 2

JRE,这一概念已经过时 - JRE1.8是最后一个版本。各种供应商(如Azul)为更新的版本制作JRE,但它不再是受支持的部署平台。

因此,毫不奇怪您的最终用户已经安装了它。 JRE1.8不再受支持,而且非常古老,肯定太旧无法运行您编译的内容,因为您是在最新的Java版本上编译的。

您可以告诉Java生成与javac --release 8 *.java兼容的JDK8代码,例如(或查看构建工具文档,了解如何告诉它添加此参数),但这意味着您不能使用自那时以来引入的任何API(引入了许多API),也不能使用自那时以来引入的任何Java语言功能(因此,没有var,没有record,没有"""字符串等等)。

但是,您的部署模型已经过时!

您的部署模型是:

  • 您,最终用户,安排存在一个JRE。我只能告诉您去某个地方下载一个。
  • 我将向您提供一个jar文件。
  • 您双击它。

不再建议或提供这种模型。现在很难找到JRE,也不合理指望用户安装它。充其量,您可以提供关于他们在哪里获取JRE的详细文档(不再是openjdk.org或java.com!)

这是有原因的:它从未真正起作用,Oracle/团队OpenJDK选择摆脱JRE与JDK的分发模型,可能更多地是因为他们醒悟到现实世界一直在如何部署Java应用程序,而不是因为他们试图通过改变工作方式来惹恼您。

新模型涉及您将Java运行时与您的应用程序一起提供,并由您负责维护。

有各种教程可以指导您如何做到这一点,jlink是其中的关键部分(因此在您的搜索中包括它)。或者,这并不特别困难,因为即使在10年前JRE部署模型仍然存在时,这已经相当流行了:您可以将整个JDK与您的jar文件一起提供并制作一个简单的安装程序。像launch4j这样的工具使用户能够轻松启动它(只需单击EXE文件)。

JRE部署模型的问题概括如下:

  • 您的最终用户将与Oracle签订合同以下载JRE,将其安装在其系统上,然后Oracle和用户将共同努力保持其最新。如果未执行此操作(例如,用户从其系统启动文件夹中删除jusched.exe),则表示Oracle有可能因未更新而导致JRE不安全。
  • 作为应用程序供应商,您实际上只能告诉用户他们需要首先访问oracle.com或java.com等。这很尴尬。
  • 您无法保证他们所安装的JRE是否兼容。Java基本上是向后兼容的,但很容易发生这种情况,例如,您的应用程序在Java 10上无法运行,但在Java 8上可以。如果有人安装了JRE10,那么您的应用程序将“运行”并崩溃。在JRE8、9、10、11、12、13、14、15、16、17、18和19上测试您的应用程序非常困难,因此人们没有这样做,这导致应用程序经常失败。
  • 由于它是系统级的东西,JRE需要宣布自己所在的位置,并注册自己作为运行任何.jar文件的工具。这使得安全情况变得更加复杂。

与新模型相比(这是在成为官方模型之前很多人已经在使用的模型,因为上面列出的旧模型的问题):

  • 您精确部署您想要并经过测试的JDK/JRE。
  • 无需通知用户需要访问java.com。
  • 这个JDK/JRE不需要向系统宣布自己。
  • 不需要频繁更新;由于它不会注册自己来运行.jar文件或以其他方式参与任何操作,除了您的应用程序之外,大多数JDK安全问题无法被利用,除非应用程序本身涉及其中/可以通过应用程序修复。

它与主要的Java应用程序(如IntelliJ和Eclipse)已经在使用的模型相匹配

这种新模型的缺点是编写安装程序需要更多的工作。JRE的一个优点是它们体积较小,可以使用jlink来复制,其中包括可以从中剔除您的特定应用程序不需要的所有部分的树摇JDK(一种JDK)。

英文:

JRE, the concept, is obsolete - JRE1.8 was the last one. Various vendors (such as Azul) make JREs for newer versions, but it's no longer a supported deployment platform.

Hence, no wonder your end user has it installed. JRE1.8 is no longer supported and is very old, certainly too old to run what you compiled, which you compiled on the very newest java version.

You can tell your java to produce code that is JDK8 compatible with javac --release 8 *.java for example (or check your build tool docs for how to tell it to add this parameter), but it means you can't use any API introduced since then (and lots has been introduced), nor any java language feature introduced since then (so, no var, no record, no &quot;&quot;&quot; strings, etcetera).

But, your deployment model is obsolete!

Your deployment model is:

  • You, end user, arrange for a JRE to exist. All I can do is tell you to go download one someplace.
  • I shall ship you a jar file.
  • You double click it.

This model is no longer recommended or available. Finding a JRE is now quite difficult and it is not reasonable to expect users to have it. At best you can ship extensive documentation about where they can get one (not openjdk.org or java.com, not anymore!)

There's a reason for that: It really never worked well, oracle/team OpenJDK's choice to get rid of the JRE vs JDK distribution model is perhaps more them just waking up and realizing how the real world has been deploying java apps, rather than that they are trying to annoy you by changing how things work.

The new model involves you shipping the java runtime together with your app and you taking on the responsibility of maintaining it.

There's various tutorials out there on how to do this, jlink is a key part of it (so include that in your searches). Alternatively, and this isn't particularly hard either, as this was already quite popular even 10 years ago when the JRE deployment model was still a thing: You can ship an entire JDK with your jars and make a simple installer. Things like launch4j exist that make it real easy for your users to launch it (simply click the EXE).

The problem with the JRE deployment model in a nutshell:

  • Your end users would 'contract' with oracle to download a JRE, install it on their system, and oracle+user would work together to keep it up to date. Failure to do this (for example, users getting jusched.exe out of their system start up folder) means oracle catches the heat for having a JRE that is probably insecure (due to not being updated).
  • All you could really do as app vendor is tell the user they need to go to oracle.com or java.com or whatnot first. This was awkward.
  • You have no real guarantee that the JRE they do have is compatible. Java is mostly backwards compatible but it can easily happen that, say, your app does not run on java 10 but it does on java8. If someone installs a JRE10, then your app 'runs' and crashes. It is very difficult to test your app on JRE8,9,10,11,12,13,14,15,16,17,18, and 19, so people didn't, and this led to apps failing all the time.
  • Because it's a system thing, the JRE needs to announce where it is at, and register itself as being the thing to use to run any .jar file. This makes the security situation considerably more tricky.

Contrast to the new model (which is the model lots of folks already used before this became the official model, because of the issues with the old model listed above):

  • You deploy precisely the JDK/JRE you want, and tested with.
  • There is no need to inform the user about needing to go to java.com
  • There is no need for this JDK/JRE to announce itself to the system.
  • There is less need to keep it updated; given that it doesn't register itself to run .jar files or otherwise gets involved in being executed for anything, other than your app, and most JDK security issues cannot be exploited unless the app is 'in on it' / can be fixed app-side.
  • It matches what the major java apps, such as intellij and eclipse, were already doing.

The downside of this new model is that it's a lot more effort to write an installer. One advantage of JREs, that they are smaller in size, can be reproduced with jlink that, amongst other things, can make a tree-shaken JDK (a JDK with all parts that your specific app does not need, taken out of it).

huangapple
  • 本文由 发表于 2023年3月7日 21:44:00
  • 转载请务必保留本文链接:https://go.coder-hub.com/75662763.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定