修改JAR包内的文件

106
我想修改我的jar文件中的一个文件。是否可以在我的应用程序内部进行此操作而不需要提取和重新打包?
我想要修改的文件是配置文件,大多是基于xml的。
我之所以对不解压缩感兴趣是因为该应用程序使用launch4j封装,如果我解压它,就无法再创建.exe文件。

1
我希望将补充文件保存在应用程序内,而不是在文件系统上创建临时文件。 - Hamza Yerlikaya
尝试这个解决方案 https://dev59.com/Hm445IYBdhLWcg3we6V9#4837522我使用了它,我的问题得到了解决。 - A. Magalhães
请您取消接受当前已被接受的答案吗?它得分为负数,绝对没有帮助。 - Dici
14个回答

104

你可以在 jar 命令中使用 u 选项。

来自 Java 教程:

jar uf jar-file input-file(s)

如果归档中已经存在与正在添加的文件相同路径名的文件,则会覆盖。

请参阅更新JAR文件

比重新制作整个jar文件要好得多。也可以从程序内部调用此功能。尝试在Java中运行命令行


1
太棒了!但是他们添加的路径名很有趣。例如,Bitbucket.foo.bar而不是现有的com.etc.etc。 - StarWind0
没有这个文件或目录。 - LoukasPap

42
你可以使用Vim: <代码> vim my.jar 如果你的环境中有“解压缩”命令,Vim能够编辑压缩的文本文件。

6
太好了。导航到您要查找的文件,然后按Enter键。编辑文件,然后输入:wq以保存! - Michael Butler
2
还需要在您的环境中安装zip,才能保存更改。感谢您的回答! - troig

11

Java的jar文件与zip文件格式相同 - 因此,如果您拥有可以修改存档的zip文件实用程序,那么您就可以入门了。第二个问题是,如果您想重新编译一个类或其他内容,您可能只需要重新构建jar文件;但是文本文件或某些文件(例如xml)应该很容易进行修改。


10

众所周知,你无法在JAR文件中更改文件而不重新扫描JAR。如果使用Launch4J,情况更糟,必须在更改JAR后重新构建EXE。因此,请勿选择这种方法。

将配置文件放在JAR中通常是一个坏主意。这是我的建议:在一些预定的位置(如主目录、\Program Files\等)中搜索配置文件。如果找到配置文件,则使用它。否则,使用JAR中的文件作为备选项。如果这样做,您只需在预定位置编写配置文件,程序将自动获取它。

另一个好处是,如果升级软件,修改后的配置文件不会被覆盖。


5

5
我有一个类似的问题,需要修改/更新JAR文件中的XML文件。
JAR文件是由Spring-boot应用程序创建的,文件位于BOOT-INF/classes/properties位置。
我参考了文档并尝试使用以下命令替换/更新文件:
jar uf myapp.jar BOOT-INF/classes/properties/test.xml
但是,它不会更改给定位置的文件。我尝试了所有选项,但都无法工作。
注意:我正在执行命令的位置是JAR文件所在的位置。
我找到的解决方法是:
1.从JAR文件的当前位置,我创建了文件夹BOOT-INF/classes/properties 2.将test.xml文件复制到位置BOOT-INF/classes/properties中。 3.再次运行相同的命令。jar uf myapp.jar BOOT-INF/classes/properties/test.xml XML文件已在JAR文件中更改。
基本上,您需要创建一个文件夹结构,就像文件在jar文件中所在的位置一样。将文件复制到该位置,然后执行命令。
文档的问题在于,它没有足够的示例以及对常见场景的解释。

2
这可能比你短期内想要处理的工作更多,但我认为从长远来看,你应该考虑使用Ant(或Maven,甚至Bazel)而不是手动构建jar文件。这样,如果你使用Eclipse,只需点击ant文件即可重新构建jar包,非常有益。
另外,如果你预计需要经常替换这些配置文件,或者需要将其分发给多个方,那么最好根本不要将配置文件放在jar包中。

2
同意。但是,您可能希望在JAR中放置一个“默认”配置文件,以便如果外部配置文件发生故障(损坏、删除等),您可以回退到默认配置。 - Thomas Owens
真的 - 虽然我不知道有多少应用程序会在没有它们的配置文件的情况下继续运行... - dimo414

1

使用WinRAR提取jar文件,然后使用CAVAJ:

Cavaj Java反编译器是一款免费的图形化实用程序,可以从CLASS文件中重构Java源代码。

如果需要,这里有视频教程: https://www.youtube.com/watch?v=ByLUeem7680


好的,这里的答案是使用“CAVAJ”软件。如果需要额外的解释,链接只是一个补充。 - Tomasz Mularczyk

1

是的,您可以使用SQLite从JAR文件内部读取或写入数据库,这样您就不必提取然后重新打包它,按照我的帖子http://shoaibinamdar.in/blog/?p=313进行操作。

使用语法“jdbc:sqlite::resource:”,您将能够从JAR文件内部读取和写入数据库。


1
你好,欢迎来到stackoverflow。我已经从你的帖子中删除了缩写词。一般来说,在这里使用文本消息风格的速记不太合适。如果你在答案中包含更多来自你的博客的细节,那么我认为这个答案会是一个很好的答案,这样即使有人没有阅读博客或者它在将来被移动到另一个URL上,他们也能从你的答案中学到一些东西。 - Flexo

1

为了扩展dfa所说的内容,原因是因为jar文件设置类似于zip文件。如果您想修改文件,则必须读取所有条目,修改要更改的条目,然后将条目写回jar文件中。我以前不得不这样做,那是我能找到的唯一方法。

编辑

请注意,这是使用Java内部jar文件编辑器,即文件流。我确定有一种方法可以做到这一点,您可以将整个jar读入内存,修改所有内容,然后写回到文件流中。我认为像7-Zip和其他实用程序正在执行的就是这样,因为我认为zip标头的ToC必须在写入时定义。但是,我可能是错的。


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