【问题标题】:Modify Executing Jar file修改执行Jar文件
【发布时间】:2011-01-28 15:48:31
【问题描述】:

你好 Stack Overflow 的朋友们。我有一个简单的问题,我担心没有简单的解决方案,我需要关于如何进行的建议。我正在开发一个打包为可执行 JAR 的 java 应用程序,但它需要在执行期间修改它的一些 JAR 文件内容。在这个阶段我遇到了一个问题,因为某些操作系统锁定了文件,阻止了对它的写入。

用户必须在应用程序退出时看到 jar 文件的更新版本,尽管我可以非常灵活地了解如何实现这一点。一个干净高效的解决方案显然是可取的,但便携性是唯一的硬性要求。

以下是我可以看到的解决问题的三种方法,请随时发表评论或建议其他人。

  1. 告诉 Java 解锁 JAR 文件以进行写入(这似乎不可能,但这是最简单的解决方案)
  2. 在应用程序启动时将可执行类文件复制到临时文件中,使用类加载器加载这些文件并从初始 JAR 文件中卸载这些文件。(对类加载器没有太多经验,但希望 JVM 会变得聪明足以意识到原来的 JAR 已不再使用,因此将其解锁)
  3. 将第二个可执行 JAR 文件放在第一个内部,在启动时将内部 jar 提取到临时文件,使用复制的内部 JAR 调用一个新的 java 进程并将外部 JAR 的位置传递给它,第一个进程退出,第二个进程修改外部 jar 不受阻碍。(这会起作用,但我不确定是否有一种独立于平台的方式可以让一个 java 应用程序调用另一个)

我知道这是一个奇怪的问题,但我们将不胜感激。

【问题讨论】:

  • 您能否说明为什么需要在执行期间修改 jar 文件?
  • @pinkynobrain 你在想老派的蚂蚁方式,我建议你通过示例免费电子书阅读 maven,你会发现你的建议毫无意义.. 我不是想冒犯你只是想帮助你..我们不是都去过那里
  • 你想要实现什么 - 一个自我更新的应用程序?
  • @c0mrade 你到底指的是什么?
  • JAR 文件中捆绑了几个包含用户信息的文件,用户在程序执行过程中添加信息,这些信息必须添加到 JAR 文件中。因为该应用程序的目的是小巧且易于传输,所以我真的希望将其保留为单个 jar 文件。

标签: java file-io jar classloader executable-jar


【解决方案1】:

一个选项:

让程序编写 JAR 文件的修改副本

在 JAR 文件中包含带有实用程序的第二个 JAR,该实用程序在执行时会删除原始 JAR 文件并重命名修改后的副本以匹配原始 JAR 文件。

当您的程序退出(并且已进行更改)时,提取此实用程序并在其自己的 JVM 中启动它(使用 Runtime.getRuntime().exec())。该实用程序将等待锁定解除原始的、未修改的 JAR,然后执行其业务并退出。

对于用户而言,JAR 文件似乎会在退出时更新(或足够接近!)。

【讨论】:

  • 嘿,谢谢你的回答,这绝对是另一种解决方案,尽管它仍然与我的选项 3 存在相同的问题。我想使用 exec("java") 是相当便携的,我只是希望有是一种真正独立于平台的方式,可以从另一个 Java 应用程序中生成一个 Java 应用程序。
  • 虽然 Java 比许多其他语言更独立于平台,但它在很多方面并不完美,而且像执行 jar 文件这样的方式也没什么大不了的在基于平台的开关中(如果它甚至需要有所不同 - 我认为'java '适用于unix和windows,不确定osx)。
  • 如何在实际调用之前在平台independent 中获取执行Runtime.getRuntime().exec() 所需的所有信息。我认为System.getProperties() 方法有一些有用的信息。
【解决方案2】:

老实说,我认为你的方法是错误的。这根本不适合部署 java 的默认方式。您修改后的文件只需要保存到某个地方的 db 或 xml 文件 - 这是唯一明智的方法。

任何事情都只是“逆风而行”——你可能会费力地让它发挥作用,但它最终会咬到你或客户。

【讨论】:

  • 很抱歉你不喜欢这个答案。对于重命名、锁定等问题,我只是表达我的观点,即您试图强制提供一个不能很好地解决问题的解决方案。
  • 所以这将是一个评论,而不是一个答案
猜你喜欢
  • 2010-10-31
  • 1970-01-01
  • 2011-01-12
  • 2010-11-16
  • 1970-01-01
  • 1970-01-01
  • 2020-12-25
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多