【问题标题】:How do I bundle a JRE in my JAR, so that it can run on systems without Java?如何在我的 JAR 中捆绑 JRE,以便它可以在没有 Java 的系统上运行?
【发布时间】:2017-12-12 11:36:10
【问题描述】:

我想在我的可执行 JAR 中捆绑一个 JRE,以便该 exe 可以在任何系统上运行。

我已经尝试过Launch4j,但这种方法需要我同时发布 JRE 和 exe。根据我的要求,我不应该使用安装程序来发布,也不应该在客户端机器上提取/安装 JRE。

如何将 JRE 放入 JAR 并使用它?

【问题讨论】:

标签: java bundle exe packaging maven-shade-plugin


【解决方案1】:

您不能将 JRE 放入 JAR 文件中。 (嗯,你可以......但它不会有帮助。)

您需要做的是构建和分发安装程序。创建安装程序的推荐方法是使用商业或开源安装程序生成器。 (Google 会帮你找到一个。)

也可以在 ZIP 文件中嵌入 JRE,如下所述:

ZIP 文件包含 JRE 和应用程序 JAR 以及它需要的其他文件。用户必须解压缩 ZIP 文件才能安装应用程序。


.. 但它在近 100 MB 的客户端系统中复制了总 JRE。有没有可能让JRE轻量化?

不是真的。分发 JRE 的最(合法)轻量级方法是分发 Oracle Java 安装程序。请注意,Java 二进制许可证禁止分发缩减的 JRE。如果你想走这条路先和律师谈谈!


使用嵌入式 JRE 分发 Java 应用程序可以说是一件坏事:

  • 它用多个 JRE 填满了用户的磁盘。
  • JRE 往往被隐藏起来/对正常的安全更新/修补/审核不可见。因此,它们往往会成为一种安全责任。
  • 您需要定期更新您的可分发文件...以避免将过期/不安全的 JRE 强加给毫无戒心的用户。

从 Java 9 开始,有一个比在安装程序中包含标准 JRE 更好的解决方案。使用新的jlink 实用程序为您的应用程序创建定制的 JRE;教程见https://www.baeldung.com/jlink,Oracle 见Jlink manual entry

请注意,jlink 解决了我们上面提到的嵌入式 JRE 的问题。但它明确规定您有责任1以新的 jlink 可分发文件的形式向您的用户提供 JVM 安全补丁。

1 - 实际上,始终是应用程序供应商/供应商的责任,为客户升级嵌入式 JRE 提供建议和帮助。不幸的是,许多供应商忽略了这一点,导致客户运行具有已知 Java 漏洞的应用程序,而 Sun/Oracle 因供应商的失误而受到指责……不公平。

【讨论】:

    【解决方案2】:

    launch4j 确实对我有用

    首先创建一个app文件夹 然后打开launch4j并输入jar文件,输出文件(应该在app文件夹中)和图标(请在app文件夹中)。然后转到 jre 部分并在捆绑的 jre 路径中键入 jre-{version ur using} 然后将选项仅使用私有 jdk 运行时然后将 min 版本放入您的 java 版本,然后进行 jdk 安装并复制 bin 和 lib 文件夹然后创建一个 jre-{version ur using} 文件夹,然后将它们粘贴进去。然后将其编译成 exe!

    【讨论】:

      【解决方案3】:

      迟到总比没有好。我在 pom.xml 中使用了 maven-shade-plugin 如下:

              <plugin>
                <artifactId>maven-shade-plugin</artifactId>
                <version>2.4.3</version>
                <configuration>
                    <transformers>
                        <transformer
                          implementation="org.apache.maven.plugins.shade.resource.ServicesResourceTransformer"/>
                        <transformer
                          implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
                            <mainClass>${mainClass}</mainClass>
                        </transformer>
                    </transformers>
                    <!-- If false the shaded artifact takes the normal artifact name, such as,  "core-tools-1.0-SNAPSHOT.jar"-->
                    <!-- Meanwhile, another non-shaded version takes the prefix Original, such as  "Original-core-tools-1.0-SNAPSHOT.jar"-->
                  <shadedArtifactAttached>false</shadedArtifactAttached>
                    <!-- Exclude signed Manifests from the UberJar -->
                    <filters>
                        <filter>
                            <artifact>*:*</artifact>
                            <excludes>
                                <exclude>META-INF/*.SF</exclude>
                                <exclude>META-INF/*.DSA</exclude>
                                <exclude>META-INF/*.RSA</exclude>
                            </excludes>
                        </filter>
                        <filter>
                            <artifact>*:*</artifact>
                            <includes>
                                <include>sun/misc/**</include>
                            </includes>
                        </filter>
                    </filters>
                  </configuration>
                  <executions>
                      <execution>
                          <phase>package</phase>
                          <goals>
                            <goal>shade</goal>
                          </goals>
                      </execution>
                  </executions>
              </plugin>
      

      【讨论】:

      • 这并没有解决所提出的问题。带阴影的 JAR 不包含嵌入式 JRE。
      • 所以......在这种情况下......最好不要迟到一个离题的答案。
      猜你喜欢
      • 2011-03-02
      • 2010-11-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-11-17
      • 1970-01-01
      • 2011-02-21
      • 2021-02-16
      相关资源
      最近更新 更多