Why is it impossible to delete entries from the jar file?

You can add new entries to the jar file using the jar tool.
You can change some entries in the jar file using the jar tool.
But it is not possible to delete some entries from the jar file.
Why?

+4
source share
6 answers

The purpose of the jar file is to pack the Java application. There is no need to delete entries as you package your deployment application.

Here are three possible ways to do this.

  • You can use winzip or other zip utility
  • You can simply use the jar with the appropriate entries (Remove the jar and repack).
  • You can do it programmatically ...

... view, see below:

import java.io.*; import java.util.*; import java.util.zip.*; import java.util.jar.*; public class JarUpdate { /** * main() */ public static void main(String[] args) throws IOException { // Get the jar name and entry name from the command-line. String jarName = args[0]; String fileName = args[1]; // Create file descriptors for the jar and a temp jar. File jarFile = new File(jarName); File tempJarFile = new File(jarName + ".tmp"); // Open the jar file. JarFile jar = new JarFile(jarFile); System.out.println(jarName + " opened."); // Initialize a flag that will indicate that the jar was updated. boolean jarUpdated = false; try { // Create a temp jar file with no manifest. (The manifest will // be copied when the entries are copied.) Manifest jarManifest = jar.getManifest(); JarOutputStream tempJar = new JarOutputStream(new FileOutputStream(tempJarFile)); // Allocate a buffer for reading entry data. byte[] buffer = new byte[1024]; int bytesRead; try { // Open the given file. FileInputStream file = new FileInputStream(fileName); try { // Create a jar entry and add it to the temp jar. JarEntry entry = new JarEntry(fileName); tempJar.putNextEntry(entry); // Read the file and write it to the jar. while ((bytesRead = file.read(buffer)) != -1) { tempJar.write(buffer, 0, bytesRead); } System.out.println(entry.getName() + " added."); } finally { file.close(); } // Loop through the jar entries and add them to the temp jar, // skipping the entry that was added to the temp jar already. for (Enumeration entries = jar.entries(); entries.hasMoreElements();) { // Get the next entry. JarEntry entry = (JarEntry)entries.nextElement(); // If the entry has not been added already, add it. if (!entry.getName().equals(fileName)) { // Get an input stream for the entry. InputStream entryStream = jar.getInputStream(entry); // Read the entry and write it to the temp jar. tempJar.putNextEntry(entry); while ((bytesRead = entryStream.read(buffer)) != -1) { tempJar.write(buffer, 0, bytesRead); } } } jarUpdated = true; } catch (Exception ex) { System.out.println(ex); // Add a stub entry here, so that the jar will close without an // exception. tempJar.putNextEntry(new JarEntry("stub")); } finally { tempJar.close(); } } finally { jar.close(); System.out.println(jarName + " closed."); // If the jar was not updated, delete the temp jar file. if (!jarUpdated) { tempJarFile.delete(); } } // If the jar was updated, delete the original jar file and rename the // temp jar file to the original name. if (jarUpdated) { jarFile.delete(); tempJarFile.renameTo(jarFile); System.out.println(jarName + " updated."); } } } 
+3
source

No one answered the original question Why? The answers just provide tips on how to do this.

So why?

Jar and zip files are compressed files that have a set of files or directives, commonly called records. The structure / format of jar / zip files is a sequential listing of entries (in addition to the header of the zip file format).

Each entry has a header that contains information about the entry, for example. its name, type, byte length (and others).

Now, using this sequential list of records, how would you remove a record from the middle of a file? This would leave a β€œhole” in the middle of the file. The only way to delete a record (without re-creating the archive without deleting the record) will require copying the contents of the zip file, starting from the record to the beginning of the current (deleted) record, as well as cutting the length of the zip file along the length of the deleted record.

Imagine what this would mean if you have an archive with tens or hundreds of MB? If you delete the entry at the beginning, you will have to copy almost the entire contents of the file to several bytes (or kilobytes) so as not to leave a space in the file.

So why.

This structure makes it easy to add new entries, because they can be added to the end of the file easily, but (write) delete cannot be performed efficiently.

+3
source

Why?

Perhaps because the jar command is similar to the unix command of the tar command. Both are intended for creating archives and are not intended for managing them.

Alteratives:

  • If you need to manually fool, just use the 7-zip tool.
  • If you want to (re) create a jar ant programmatically - your friend
+2
source

Just to be complete.

The old version of jar does not include the -d option (which allows you to remove it), it was added later. Therefore, use the new version of the jar tool or one of the other alternatives for the archive tool to delete the file.

If the checkbox is signed, do not forget to remove the signature and resign

+1
source

Use cmd commands - zip -dc: /path/path/file.jar path / path / file .XMLSchema

java example http://www.mkyong.com/java/how-to-execute-shell-command-from-java/

0
source

This is not impossible. You can do this with any zip utility.

You just can't do the jar command.

0
source

Source: https://habr.com/ru/post/1312895/


All Articles