1

I'm currently working on a application that installs mods into Minecraft and I have almost finished version 3.1DEV, the only thing that is stoping me is that my code just won't remove the META-INF, here is my code

        ZipInputStream modZip = new ZipInputStream(new FileInputStream(mod.getDir()));
        ZipInputStream minecraftZip = new ZipInputStream(new FileInputStream(new File(mcDir + "\\bin\\", "minecraft.jar")));
        ZipOutputStream tmpZip = new ZipOutputStream(new FileOutputStream(new File("temp\\tmp.jar")));
        byte[] buffer = new byte[1024];

        for(ZipEntry ze = modZip.getNextEntry(); ze != null; ze = modZip.getNextEntry())
        {
            tmpZip.putNextEntry(ze);
            for(int read = modZip.read(buffer); read != -1; read = modZip.read(buffer))
            {
                tmpZip.write(buffer, 0, read);
            }
            tmpZip.closeEntry();
        }
        modZip.close();


        for(ZipEntry ze = minecraftZip.getNextEntry(); ze != null; ze = minecraftZip.getNextEntry())
        {
            try
            {
                boolean isMetaInf = false;

                if(ze.getName().contains("META-INF"))
                {
                    isMetaInf = true;
                }

                if(!isMetaInf)
                {
                    tmpZip.putNextEntry(ze);
                    for(int read = minecraftZip.read(buffer); read != -1; read = minecraftZip.read(buffer))
                    {
                        tmpZip.write(buffer, 0, read);
                    }
                    tmpZip.closeEntry();
                }
            }
            catch(Exception e)
            {
                continue;
            }
        }
        minecraftZip.close();

        tmpZip.flush();
        tmpZip.close();

        File tmp = new File("temp//tmp.jar");
        tmp.renameTo(new File("temp//minecraft.jar"));
        File minecraft = new File(mcDir + "\\bin\\minecraft.jar");
        minecraft.delete();
        FileUtils.copyFile(new File("temp\\minecraft.jar"), minecraft);
        tmp.delete();

Any links or examples are welcome

  • Liam, Hachi Software CEO
Liam Haworth
  • 848
  • 1
  • 9
  • 27
  • I am not sure whether you read SO licensing terms, it is CC-Wiki, content here can be used without authorization (AFAIK), if you think it shouldn't be distributable, please remove. – kosa Jan 16 '12 at 05:40

1 Answers1

0

The problem is with the logic, let's walk through it:

  1. The first time you find the META-INF folder, you set the flag to true. Nothing else in the loop can occur, so we continue
  2. On the next loop iteration, you reset the flag to false and go into the !isMetaInf section
  3. The zip entry is added to the temporary zip:

    tmpZip.putNextEntry(ze);

  4. You write the entire minecraft zip, from start to finish into the temp zip:

    for(int read = minecraftZip.read(buffer); read != -1; read = minecraftZip.read(buffer))
    {
        tmpZip.write(buffer, 0, read);
    }
    tmpZip.closeEntry();
    
  5. At this point you don't break out of the loop, so this process is repeated for every file inside the jar.

If you simply remove the manual reading and writing loop, you can allow the ZipOutputStream to do all the writing for you when you call close() at the end, or if you use Java 7 you can make this code very simple with a try-with-resources:

public static void copyWithoutMetaInf(final String originalZip, final String newZip) throws IOException
{
    try (final ZipInputStream zip = new ZipInputStream(new FileInputStream(originalZip));
         final ZipOutputStream zop = new ZipOutputStream(new FileOutputStream(newZip)))
    {
        ZipEntry entry;
        while((entry = zip.getNextEntry()) != null)
        {
            if(!entry.getName().contains("META-INF"))
            {
                zop.putNextEntry(entry);
            }
        }
    }
}

public static void main(String[] args) throws IOException
{
    copyWithoutMetaInf("1.6.4.jar", "copy.jar");
}

Or without, for older versions:

public static void copyWithoutMetaInf(final String originalZip, final String newZip) throws IOException
{
    final ZipInputStream zip = new ZipInputStream(new FileInputStream(originalZip));
    final ZipOutputStream zop = new ZipOutputStream(new FileOutputStream(newZip));
    ZipEntry entry;
    while((entry = zip.getNextEntry()) != null)
    {
        if(!entry.getName().contains("META-INF"))
        {
            zop.putNextEntry(entry);
        }
    }
    zip.close();
    zop.close();
}
MrLore
  • 3,759
  • 2
  • 28
  • 36
  • Does this method work actually? It seems putNextEntry only creates the metadata, you still need to write the file contents http://stackoverflow.com/questions/30859295/removing-a-jar-files-meta-inf-folder-in-java#comment49761303_30859295 – Thilo Jun 16 '15 at 05:23