从OpenJDK Windows创建jre

41

我们正在从Oracle JDK/JRE切换到OpenJDK。现在我只找到了JDK,但我还想从OpenJDK获取JRE。这是为了在没有完整的JDK的情况下在客户端安装我们的应用程序。

有没有办法从Windows X64的OpenJDK创建JRE包?


你知道OpenJDK是一个项目名称吗?它并不指代JDK/JRE发行版。 - Thorbjørn Ravn Andersen
实际上,在许多Linux发行版上,它也被用作分发的标签(实际上是Linux软件包管理器软件包)的标签。 - Stephen C
@titou10,没有单独的JRE,因为它不需要。它都包含在JDK分发中。 - jwenting
2
@jwenting 我绝对不会将完整的JDK与我的Eclipse RCP应用程序捆绑在一起,并在分发中添加约300MB... - titou10
1
@titou10,无论如何你都不应该捆绑运行时,因为许可证已经不再允许这样做了。我进行了一些比较,对于1.8版本,完整的JDK减去文档和包含的JRE的大小几乎与仅有的JRE相同。预计11版本也会是这样。所以你只能节省一点点空间,最多只有几百K。 - jwenting
12个回答

31
受到文章 Using jlink to Build Java Runtimes for non-Modular Applications 的启发,我使用以下命令:
  1. java --list-modules 获取所有可用的OpenJDK模块列表
  2. jlink --no-header-files --no-man-pages --compress=2 --add-modules <步骤1中的模块列表> --output java-runtime 创建一个紧凑的jre。
对于OpendJDK 12,这是我最终使用的命令: jlink --no-header-files --no-man-pages --compress=2 --add-modules java.base,java.compiler,java.datatransfer,java.desktop,java.instrument,java.logging,java.management,java.management.rmi,java.naming,java.net.http,java.prefs,java.rmi,java.scripting,java.se,java.security.jgss,java.security.sasl,java.smartcardio,java.sql,java.sql.rowset,java.transaction.xa,java.xml,java.xml.crypto,jdk.accessibility,jdk.aot,jdk.attach,jdk.charsets,jdk.compiler,jdk.crypto.cryptoki,jdk.crypto.ec,jdk.crypto.mscapi,jdk.dynalink,jdk.editpad,jdk.hotspot.agent,jdk.httpserver,jdk.internal.ed,jdk.internal.jvmstat,jdk.internal.le,jdk.internal.opt,jdk.internal.vm.ci,jdk.internal.vm.compiler,jdk.internal.vm.compiler.management,jdk.jartool,jdk.javadoc,jdk.jcmd,jdk.jconsole,jdk.jdeps,jdk.jdi,jdk.jdwp.agent,jdk.jfr,jdk.jlink,jdk.jshell,jdk.jsobject,jdk.jstatd,jdk.localedata,jdk.management,jdk.management.agent,jdk.management.jfr,jdk.naming.dns,jdk.naming.rmi,jdk.net,jdk.pack,jdk.rmic,jdk.scripting.nashorn,jdk.scripting.nashorn.shell,jdk.sctp,jdk.security.auth,jdk.security.jgss,jdk.unsupported,jdk.unsupported.desktop,jdk.xml.dom,jdk.zipfs --output java-runtime

这在OSX上也很好用!我跳过了所有以“jdk.”开头的行,我的(虽然非常小而独立的)应用程序使用生成的运行时完美运行。 - emllnd

16

正如其他人所提到的,自从Java 9开始,JDK不再分发单独的JRE。您需要使用jlink并指定您的代码依赖的模块来生成自定义的jre。

因为这可能会让人感到麻烦,我创建了一个基于Web的工具,以便更轻松地从OpenJDK实现(例如Oracle HotSpot、Eclipse OpenJ9或Amazon Corretto)中使用jlink创建自定义JRE。该工具将根据您的需求给出正确的jlink命令。

我还包括了一种制作标准Java SE JRE的方法,适用于那些只想要基本轻量级(约40-60 MB)JRE的人。如果您知道如何使用终端,制作适用于JDK 9及以上版本的通用JRE只需要不到2分钟。

请在此处尝试 - EasyJRE:https://justinmahar.github.io/easyjre/


非常感谢。这是一个真正令人惊叹的工具。 - Danish Ansari

6

我将发布比SteinarH发布的内容稍微简单一些的东西。我不想自己编译那个列表,所以......这个工具可以为您完成这项工作。此外,为了更加简洁,我不会将其标记为java-runtime,而是jre-11(或者您正在使用的任何版本)。

以下是PowerShell代码:

jlink --no-header-files --no-man-pages --compress=2 --add-modules $($(java --list-modules) -join "," -replace "@[0-9]*") --output jre-11


你正在将JDK中的所有模块复制到jre中吗?那有什么好处呢? - Satish Patro
我可能会说(尽管在我需要它的时候它起作用了),这个答案现在有点不相关了。然而,它是在剥离jdk文档和头文件。这基本上就是JRE所拥有的。如果您不需要或不想要所有模块可用,那么您就不需要以这种方式进行操作。这已经过时了,因为您也可以在Windows上使用Chocolatey,其中包含“adoptopenjdk11jre 11.0.11.900 [Approved]”。无需自己操作。 - Maxs728
对于那些感兴趣的人,应该说明一下命令是 choco install -y adoptopenjdk11jre,它还会为您处理环境变量。 - Maxs728

6

您也可以在此处找到JRE版本:https://adoptopenjdk.net/releases.html - Dmitri Ciornii

2
根据构建OpenJDK文档1

Windows XP不是受支持的平台,但所有更新的Windows应该能够构建OpenJDK。

然后它继续解释了需要使用Cygwin进行构建,本地编译器和库的要求以及“引导”JDK的问题,后者是编译源代码树中的Java类所必需的。
但明显的暗示是你可以在Windows上构建OpenJDK并为Windows构建...即使最终结果不被Oracle或OpenJDK项目支持。
请注意,构建文档描述了创建JRE和JDK“映像”的制作目标。我认为它是在说这些是可以复制到目标系统并使用的二进制树。您可以从中创建ZIP文件...
但更简单的方法是使用“jlink”生成类似于JRE的可执行文件;请参见接受的答案
@Andrew Henle指出,在自己的JRE中滚动存在成本和(如果将自己放在公司律师的思维方式中)风险。无论您只是内部使用还是向客户提供。如果这是一个问题,您会陷入困境:
  • 从Java 9开始,Oracle根本不提供JRE发行版。不是针对Oracle Java。也不是针对OpenJDK Java。就Oracle而言,JRE在Java 8之后结束。

  • 您为自己构建的任何内容都是成本和风险。

幸运的是,有第三方供应商为Windows上的Java提供JRE分发。(AdoptOpenJDK和Azul在撰写本文时都提供)。
或者,只需使用Oracle JDK分发版。磁盘空间便宜,网络速度快。
1-该链接适用于文档的Java 9版本。对于其他版本,您应该能够在源代码树中找到相应的“building.html”文档。

1
考虑到从OpenJDK“自己制作”Windows JRE所需的工作量(以及每次发现安全漏洞并交付更新时需要重新构建它的持续需求...),如果我是这个团队的管理者,那么必须有一个非常强大的技术原因来花费大量时间、金钱和计算资源,而没有明显的功能好处。然后,根据JRE的用途,我可能不得不向一些律师咨询,以确保自己制作不会使公司面临任何责任。 - Andrew Henle
1
问题并不在于产品的合法使用 - 而是自行编译可能会让您对产品的安全性负更多的责任。 使用最新的预构建广泛使用的开箱即用 JRE 与从源代码编译自己的 JRE 是不同的。“哦,您是通过自己编译的软件被攻击的吗?请向我们展示您如何确保构建过程生成了一个安全的产品。什么?你甚至不知道如何测试Java安全性?” 因为“我们讨厌 Oracle,可爱的!”而自己编译JRE 将使公司法律顾问非常担心。 - Andrew Henle
1
我并不是在假设,我只是指出使用自制JRE可能需要进行法律检查,“取决于JRE的用途”。例如,如果所涉及的应用程序被客户用于通过开放互联网进行在线支付(最近有一个关于如何将Java 6u45更新到TLS 1.2以便进行PayPal支付的问题... :-o)。 - Andrew Henle
1
让公司的会计师与公司律师交谈,并告诉他们停止阻碍,如果会计师适当地考虑到从源代码维护最新、安全的JRE可能需要至少一名员工全职工作,这将使公司每年花费超过100,000美元。我不会为了一个任性孩子对Oracle的厌恶而支付开发人员无用地重新发明轮子的费用。另外,回顾我上面提到的一点:开发人员甚至知道如何测试JRE安全性吗?那要花多少钱? - Andrew Henle
1
每年只需要10万美元?你确定吗?每个服务器核心每月25美元+每个PC用户每月2.5美元?而且你不需要全职开发人员来重建JRE并应用OpenJDK上游维护者的安全补丁...Oracle已同意与他们合作。 - Stephen C
显示剩余3条评论

1
自Java 9以来,您可以使用jlink创建自定义运行时环境,仅使用实际运行所需的模块,通常比传统JRE还要小。

1
我正在使用OpenJDK 11替代JRE8,因为Oracle宣布了许可证更改。我的客户对他们更改协议感到不满。
为了使其正常工作,我所做的只是将SDK文件夹重命名为JRE。
我遇到的一个问题是外部库DLL,在OpenJDK中抱怨无法在类路径中找到它。为了解决这个问题,我只需将DLL复制到system32文件夹中。
希望这可以帮助您。
Stuart

1
这确实没有解决问题,反而增加了很多混乱,在大多数专业场景中,从安全的角度来看,这是一场灾难。 - Martin Meeser

1
在这个网站上,你可以获取jdk和jre(jdk包含jre) https://adoptopenjdk.net/upstream.html
但是,如果你需要构建jre,你可以使用以下Python代码(我从@SteinarH那里获得了答案),该代码假定你在jdk二进制文件夹中,并且在上一级目录中没有名为jre的目录。
import os
jmod_str =  os.popen('java --list-modules').read()
init = jmod_str.index('@')
end = jmod_str.index('\n')
version = jmod_str[init:end]
jmod_list = jmod_str.replace(version, '').replace('\n', ',') 
jmod_list = jmod_list[:-1] if jmod_list[-1] == ',' else jmod_list
cmd = 'jlink --no-header-files --no-man-pages --compress=2 --module-path ..\jmods --add-modules '+ jmod_list + ' --output ..\jre'

1
AdoptOpenJDK似乎是唯一提供单独JRE构建的OpenJDK供应商。 - Jeff G
2
当我查看时,Azul也是如此。 - Stephen C

0

制作另一个答案的原因:

  1. 我需要一行代码来制作一个标准的JRE,以放入我的Windows安装程序中
  2. 我不想在升级Java时不得不更新它

方法:

  1. 我反向工程了Justin创建的页面的输出:https://dev59.com/AVUK5IYBdhLWcg3wsB36#54997476(非常实用)
  2. 我获取了java --list-modules的输出
  3. 选择只有以java开头的行
  4. 从每行末尾删除@versionnumber
  5. 将数组连接成逗号分隔的字符串
  6. 将其附加到jlink --output jre --compress=2 --no-header-files --no-man-pages --module-path ../jmods --add-modules

注意事项:

  • 此命令假定您已将Java bin添加到路径中
  • 这将在您运行命令的文件夹中创建其输出目录

PowerShell:

jlink --output jre --compress=2 --no-header-files --no-man-pages --module-path ../jmods --add-modules  "$((java --list-modules | Select-String -Pattern '^(java[^@]+?)@' | % {"$($_.Matches.Groups[1].value)"}) -join ',')"

0
据我所知,你可以在Azul网站下载Windows版的OpenJDK。然而,他们似乎只提供完整的JDK,如果你只需要JRE,那么你需要像Stephen C建议的那样自己构建它。

1
在官方的openjdk页面上,有一个由Oracle构建的Windows版本可供下载。 - JimmyD
2
@JimmyD 在官方OpenJDK页面上,Oracle提供了Windows的官方构建版本。 你需要发布那个作为答案。并附上链接。 - Andrew Henle
这只适用于jdk。我需要一种获取jre的方法。 - JimmyD
@jwenting - 目前来看,你无法从jdk.java.net获取JRE。据我所知,只有完整的JDK构建版本。 - Stephen C
2
@StephenC,Java11没有独立的JRE,这是事实。请记住,每个JDK也都是一个JRE。JRE只是JDK减去一些工具(编译器、反编译器等)的版本。 - jwenting

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接