Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Update a file inside a JAR in a specific directory with jar command

Tags:

java

jar

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.

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 -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.

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.

I.e. 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. 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).

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.

Any help on this is greatly appreciated!

like image 762
Acapulco Avatar asked Dec 05 '12 18:12

Acapulco


People also ask

What is CVF in jar command?

The basic format of the command for creating a JAR file is: jar cf jar-file input-file(s) The options and arguments used in this command are: The c option indicates that you want to create a JAR file. The f option indicates that you want the output to go to a file rather than to stdout.


2 Answers

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.

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 :
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. Jar creates appropriate folders too.

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

  1. Modify the extracted file
  2. update the jar using the 'u' flag. Provide the exploded directory root and jar shall update all the path elements under it.

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 ?

I used jar bundled with JDK 7 on Fedora 17.


I have verified all the steps mentioned here. Hope this helps.

like image 137
2 revs, 2 users 96% Avatar answered Oct 16 '22 00:10

2 revs, 2 users 96%


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.

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."

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."

like image 26
flup Avatar answered Oct 16 '22 00:10

flup