Replace/Add a class file to subfolder in jar using python zipfile command
<p>I have a jar file and I have a path which represents a location inside Jar file. </p>

<p>Using this location I need to replace class file inside jar(Add a class file in some cases).I have class file inside another folder which is present where jar is present(This class file i have to move to Jar).</p>

<p>Code which I am trying to achieve above objective :</p>

<pre><code> import zipfile
 import os

 zf = zipfile.ZipFile(os.path.normpath('D:\mystuff\test.jar'),mode='a')
 try:
     print('adding testclass.class')
     zf.write(os.path.normpath('D:\mystuff\testclass.class'))
 finally:
     print('closing')
     zf.close()
</code></pre>

<p>After executing above code when I saw jar below mentioned format:</p>

<pre><code>  Jar
   |----META-INF
   |----com.XYZ
   |----Mystuff
          |--testclass.class
</code></pre>

<p>Actual Output I need is -</p>

<pre><code>   Jar
    |----META-INF
    |----com.XYZ
           |--ABC
               |-testclass.class
</code></pre>

<p>How can achieve this using zipfile.write command or any other way in python?</p>

<p>I didn't find any params in write command where i can provide destination file location inside Jar/Zip file.</p>

<p>ZipFile.write(filename, arcname=None, compress_type=None)</p>

<p>Specify <code>arcname</code> to change the name of the file in the archive.</p>

<pre><code>import zipfile
import os

 zf = zipfile.ZipFile(os.path.normpath(r'D:\mystuff\test.jar'),mode='a')
 try:
     print('adding testclass.class')
     zf.write(os.path.normpath(r'D:\mystuff\testclass.class'),arcname="com.XYZ/ABC/testclass.class")
 finally:
     print('closing')
     zf.close()
</code></pre>

<p>Note: I doubt <code>test.jar</code> is your real jar name, since you didn't protect your string against special chars and the jar file opened would have been <code>'D:\mystuff\&lt;TAB&gt;est.jar'</code> (well, it doesn't work :))</p>

<p>EDIT: if you want to add the new file but remove the old one, you have to do differently: you cannot delete from a zipfile, you have to rebuild another one (inspired by <a href="http://stackoverflow.com/questions/513788/delete-file-from-zipfile-with-the-zipfile-module">Delete file from zipfile with the ZipFile Module</a>)</p>

<pre><code>import zipfile
import os

infile = os.path.normpath(r'D:\mystuff\test.jar')
outfile = os.path.normpath(r'D:\mystuff\test_new.jar')

zin = zipfile.ZipFile(infile,mode='r')
zout = zipfile.ZipFile(outfile,mode='w')
for item in zin.infolist():
    if os.path.basename(item.filename)=="testclass.class":
        pass  # skip item
    else:
        # write the item to the new archive
        buffer = zin.read(item.filename)
        zout.writestr(item, buffer)

print('adding testclass.class')
zout.write(os.path.normpath(r'D:\mystuff\testclass.class'),arcname="com.XYZ/ABC/testclass.class")

zout.close()
zin.close()

os.remove(infile)
os.rename(outfile,infile)
</code></pre>

python jar cmd zip