简体   繁体   English

使用 jar 命令更新特定目录中 JAR 中的文件

[英]Update a file inside a JAR in a specific directory with jar command

So I've been looking high and low for an answer to this and obviously haven't found a satisfactory answer.所以我一直在寻找答案,显然没有找到满意的答案。

The problem is that I want to update a JAR (or any file for that matter) inside a JAR, but said file is inside a folder structure, which I would like to avoid reproducing outside the JAR just so I can update it.问题是我想更新 JAR 内的 JAR(或任何与此相关的文件),但所述文件位于文件夹结构内,我想避免在 JAR 之外复制它,以便我可以更新它。

Example:例子:

Foo.jar (root directory)
/
|->/folder1
|
|->/folder2
|
|->/foo
    |
    |-->/bar
         |
         |---->/baz
               |
               |------>file_to_update.jar

So, if I want to update this using the jar command, I would have to first create the same folder structure outside the JAR and then do因此,如果我想使用jar命令更新它,我必须首先在 JAR 之外创建相同的文件夹结构,然后执行

jar -uf Foo.jar -C foo/bar/baz/file_to_update.jar

However I would like to avoid creating this folder structure since for certain files it can be quite deep and also because I might need to update selected files all over the container JAR, so I would not like to create so many folders with a specific structure just so the jar command can update them.但是,我想避免创建此文件夹结构,因为对于某些文件,它可能非常深,而且因为我可能需要更新整个容器 JAR 中的选定文件,所以我不想创建这么多具有​​特定结构的文件夹所以jar命令可以更新它们。

To put it in another way, I would like to tell the jar command to update a specific destination file inside a specific destination directory, using a specific source file inside a specific source directory.换句话说,我想告诉jar命令使用特定源目录中的特定源文件更新特定目标目录中的特定目标文件。

Ie something like即像

jar -uf Foo.jar -sourceFile /x/y/z/filetoupdate -destFile /a/b/c/filetoupdate 

(I know this syntax doesn't work, it's just to exemplify what I need). (我知道这种语法不起作用,只是为了举例说明我需要什么)。

Can this be done?这能做到吗? It would strike me as very odd that I would absolutely need to mimic the whole folder structure when the jar command could find a match for it or something, since I could have the need to update a file inside a folder structure that is 100 folders deep.jar命令可以找到匹配项或其他内容时,我绝对需要模仿整个文件夹结构,这让我感到非常奇怪,因为我可能需要更新 100 个文件夹深的文件夹结构中的文件. That would be overly complex to reproduce just to update the file.仅仅为了更新文件而复制会过于复杂。

Also, I know a regular ZIP utility could be used, but the one I have available in Linux is not updating the file even if it says it did (upon re-opening the jar, it has the old version intact), and right now I can't go looking for another one (company policy, no time, testing issues, you name it).另外,我知道可以使用常规的 ZIP 实用程序,但是我在 Linux 中可用的那个实用程序没有更新文件,即使它说更新了(重新打开 jar 后,旧版本完好无损),现在我不能去寻找另一个(公司政策,没有时间,测试问题,你说出来)。

Finally, if I can do this from a command line, it means I can create a batch file to update lots of specific files without having to create the folder structure.最后,如果我可以从命令行执行此操作,则意味着我可以创建一个批处理文件来更新大量特定文件,而无需创建文件夹结构。

I forgot to say that I would also like to avoid having to unjar, update, rejar the whole thing, as this JAR can go upwards to 2GB so it takes a while to do this just to, basically, add a little resource file to my gigantic JAR.我忘了说,我还想避免解压、更新、重装整个过程,因为这个 JAR 可以上升到 2GB,所以这样做需要一段时间,基本上只是向我的巨大的 JAR。

Any help on this is greatly appreciated!非常感谢您对此的任何帮助!

As the accepted answer already pointed out, you can't use neither the zip nor the jar command to insert a specific file on the file system to a specific directory inside the compressed file.正如已接受的答案已经指出的那样,您既不能使用zip也不能使用jar命令将文件系统上的特定文件插入到压缩文件内的特定目录中。

But there is this workaround , which in a nutshell extracts a specific file inside the compressed file first, you can update it and then put it back into the compressed file:但是有这个解决方法,简而言之,它首先提取压缩文件中的特定文件,您可以更新它,然后将其放回压缩文件中:

1. Extracting a single file : 1. 提取单个文件:
Consider a jar with the following contents考虑一个包含以下内容的罐子

$ jar tvf foo.jar 
 0 Thu Jan 10 00:05:06 IST 2013 META-INF/
68 Thu Jan 10 00:05:06 IST 2013 META-INF/MANIFEST.MF
 0 Thu Jan 10 00:04:30 IST 2013 x/
 0 Thu Jan 10 00:07:36 IST 2013 x/b/
 9 Thu Jan 10 00:07:36 IST 2013 x/b/hello.txt
 0 Thu Jan 10 00:04:30 IST 2013 x/a/

To extract only hello.txt, you have to give fully qualified path of the file-to-extract.要仅提取 hello.txt,您必须提供要提取的文件的完全限定路径。 Jar creates appropriate folders too. Jar 也会创建适当的文件夹。

Example :例子 :

$ jar xvf foo.jar x/b/hello.txt
inflated: x/b/hello.txt

$ tree x/
x
└── b
    └── hello.txt  
1 directory, 1 file

2. Updating a Single File 2. 更新单个文件

  1. Modify the extracted file修改解压文件
  2. update the jar using the 'u' flag.使用 'u' 标志更新 jar。 Provide the exploded directory root and jar shall update all the path elements under it.提供分解后的目录根目录,jar 将更新其下的所有路径元素。

Example:例子:

$ jar vfu foo.jar x/
adding: x/(in = 0) (out= 0)(stored 0%)
adding: x/b/(in = 0) (out= 0)(stored 0%)
adding: x/b/hello.txt(in = 23) (out= 11)(deflated 52%)

3. Which version of jar I tried this out with ? 3. 我用哪个版本的 jar 试过这个?

I used jar bundled with JDK 7 on Fedora 17.我在 Fedora 17 上使用了与 JDK 7 捆绑在一起的jar


I have verified all the steps mentioned here.我已经验证了这里提到的所有步骤。 Hope this helps.希望这可以帮助。

4129445 : An API to incrementally update ZIP files in the Sun/Oracle bug database asks for this feature to be implemented in the java api. 4129445:用于增量更新Sun/Oracle 错误数据库中的ZIP 文件的 API要求在 java api 中实现此功能。

From the Evaluation:来自评估:

"It is easy to sympathize with those who want this bug fixed. It is perhaps easier to sympathize with those who have, inadvertently, overwritten JAR files that are already in-use by a running JVM." “很容易同情那些想要修复这个错误的人。同情那些无意中覆盖了正在运行的 JVM 已经在使用的 JAR 文件的人可能更容易同情。”

and

"It would have been nice if the jar & zip APIs had allowed for mutable zip files from day one. But at this point adding mutability to jar & zip files from Java(or rather, increasing the ease of mutating them) seems likely to introduce more hard-to-debug problems." “如果 jar 和 zip API 从第一天起就允许可变 zip 文件,那就太好了。但在这一点上,从 Java 向 jar 和 zip 文件添加可变性(或者更确切地说,增加变异它们的容易程度)似乎可能会引入更难调试的问题。”

This previous discussion shows some Java source code for updating a zip (or jar) file. 前面的讨论显示了一些用于更新 zip(或 jar)文件的 Java 源代码。

It's not entirely clear to me whether this will actually be any faster than using jar -u , but at least you should be able to adapt that code so that you don't have to recreate the file structure on disk.我并不完全清楚这是否实际上比使用jar -u更快,但至少您应该能够调整该代码,这样您就不必在磁盘上重新创建文件结构。

Edit: Here is the documentation on the 'jar' utility - you can see for yourself that the particular behavior that you're looking for, while it would be useful, isn't there.编辑: 这是关于“jar”实用程序的文档- 您可以亲眼看到您正在寻找的特定行为虽然很有用,但并不存在。

I think that the reason is that the command-line interface is basically a clone of the Unix/Linux 'tar' command.我认为原因是命令行界面基本上是 Unix/Linux 'tar' 命令的克隆。 Of course, it produces zip format, rather than tar.当然,它生成 zip 格式,而不是 tar。

Edit #2 - It occurred to me that to add a file to a zip, you'd just have to strip off the central directory from the end of the file, append the new entry, and then re-write the central directory.编辑 #2 - 我想到要将文件添加到 zip,您只需要从文件末尾剥离中央目录,附加新条目,然后重新写入中央目录。 An update would be the same thing, except instead of adding the entry to the directory, you'd update the existing directory entry to point to the new zip entry.更新是同样的事情,除了不是将条目添加到目录中,而是更新现有目录条目以指向新的 zip 条目。

While exploring this possibility, I found that Java 7 includes a zip file system provider which looks like it does this, and could form the basis of a solution for what you want to do.在探索这种可能性时,我发现 Java 7 包含一个zip 文件系统提供程序,它看起来像这样做,并且可以构成您想要做的解决方案的基础。

I think this is due to how the classes in the java.util.zip package work.我认为这是由于 java.util.zip 包中的类是如何工作的。 They sit on top of streams.他们坐在溪流之上。

The ZipFile class is built on top of a ZipFileInputStream. ZipFile类建立在 ZipFileInputStream 之上。 Writing zipfiles is done by feeding the ZipEntries one by one to a ZipOutputStream.编写 zipfile 是通过将 ZipEntries 一一提供给 ZipOutputStream 来完成的。

I assume the jar executable is built on top of these classes.我假设 jar 可执行文件是建立在这些类之上的。

I too was trying to update a jar without reproducing the jar's file structure external to the jar, and for some reason the jar uf jarFileName -C ... command never let me copy the file to a child directory in the jar.我也试图在不复制 jar 外部的 jar 文件结构的情况下更新 jar,并且由于某种原因jar uf jarFileName -C ... 命令从不让我将文件复制到 jar 中的子目录。 I then tried cutting and pasting the file into the jar using ubuntu 14.04's built in archive manager (ie right click on jar file and chose "open with archive manager" then paste the file anywhere in the jar's file structure), and it worked.然后我尝试使用 ubuntu 14.04 的内置存档管理器将文件剪切并粘贴到 jar 中(即右键单击 jar 文件并选择“使用存档管理器打开”,然后将文件粘贴到 jar 文件结构中的任何位置),并且它起作用了. It's not a cli solution but it works.这不是 cli 解决方案,但它有效。 Hope this saves someone else some time.希望这可以为其他人节省一些时间。

It works , but its not the extact solution you are looking at.它有效,但它不是您正在查看的确切解决方案。

Instead of manually creating folder structure , i am asking to mention the whole path ,so mkdir will create folder and sub-directories too.hope this helps....我不是手动创建文件夹结构,而是要求提及整个路径,因此 mkdir 也会创建文件夹和子目录。希望这会有所帮助....

set /p Folder=where you want to move inside jar 
set /p File=Mention path of file to be moved 
set /p Jarfile=Where is your jar file
mkdir %Folder%
copy %File% %Folder%
jar -uvf %Jarfile% %File%
rd /s /q %Folder%
rmdir %Folder%

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM