strip-debug - debug-Infos aus mitgelieferter Lib entfernen

inflamer

Bekanntes Mitglied
Hallo zusammen,

ich liefere meine Anwendung mitsamt JRE sowie 3rd-Party-Bibliotheken aus.

Nun ist es ganz nice, wenn das Setup-Package dabei möglichst klein bleibt. Ein Weg dies zu erreichen besteht darin, die JARs umzupacken und zwar ohne Kompression, denn doppelt komprimiert ergibt genau das Gegenteil vom gewünschten Ergebnis. Wer das Script dazu verwenden will, siehe unten, bitte sehr. Das Script funktioniert im Gegensatz zum herkömmlichen ZIP-Umpacker auch bei obfuszierten JARs... ;-)

Nun würde ich gerne zusätzlich noch die Debug-Infos herausfiltern. Und zwar jene Infos, die z.B. die Zeilennummer im Source-Code angeben, wenn eine Exception geworfen wird.

Beim JRE-eigenen "jlink" gibt es dazu die Option "-strip-debug". Das Tool lässt sich jedoch nur auf die RT-Bibliothek anwenden, nicht aber auf sonstige JARs.

Frage: Kennt ihr ein Tool, welches dies tut?
Danke!

Java:
import java.io.*;
import java.text.*;
import java.util.*;
import java.util.jar.*;


public class UncompressJar {

  //----
  private static void errExit(String errMsg) {
    System.out.println(errMsg);
    System.exit(1);
  }


  //----
  public static void main(String[] args) {
    if (args.length != 2)
      errExit("Wrong number of arguments: " + args.length);

    File inputFile = new File(args[0]);
    if (!inputFile.isFile())
      errExit("Input file not found: " + inputFile);

    File outputFile = new File(args[1]);
    try {
      if (!outputFile.createNewFile()) // see if output file can be created at all
        errExit("Could not create output file: " + outputFile);
    } catch (IOException e) {
      errExit("IOException creating output file:\n" + e.getMessage());
    }

    byte[] b = new byte[123456];
    try (FileOutputStream fos = new FileOutputStream(outputFile);
         JarOutputStream jos = new JarOutputStream(fos)) {

      JarFile inputJarFile = new JarFile(inputFile);
      for (Enumeration<JarEntry> entries = inputJarFile.entries(); entries.hasMoreElements();) {
        JarEntry jarEntryIn = entries.nextElement();
        JarEntry jarEntryOut = new JarEntry(jarEntryIn);
        jarEntryOut.setCompressedSize(jarEntryOut.getSize());
        jarEntryOut.setMethod(JarEntry.STORED);
        jos.putNextEntry(jarEntryOut);

        InputStream in = inputJarFile.getInputStream(jarEntryIn);
        while (true) {
          int len = in.read(b);
          if (len > 0)
            jos.write(b, 0, len);
          else
            break;
        }
        in.close();
        jos.closeEntry();
      }
    } catch(IOException e) {
      errExit(e.getMessage());
    }

    NumberFormat nf = NumberFormat.getInstance();
    System.out.println(
        "Successfully created uncompressed copy of JAR file\n" +
        "Original size  : " + nf.format(inputFile.length()) + " Bytes\n" +
        "New size       : " + nf.format(outputFile.length()) + " Bytes\n");
  }

}
 
Zuletzt bearbeitet:

httpdigest

Top Contributor
Das kannst du dir ganz einfach mit ASM basteln. Hier ein Beispiel, um aus einer .class Datei alle Debug Infos zu entfernen:
Java:
import org.objectweb.asm.ClassReader;
import org.objectweb.asm.ClassWriter;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
public class RemoveDebugInfo {
  public static void main(String[] args) throws IOException {
    // read class file...
    FileInputStream fis = new FileInputStream(args[0]);
    ClassReader cr = new ClassReader(fis);
    ClassWriter cw = new ClassWriter(cr, 0);
    // ...remove debug info
    cr.accept(cw, ClassReader.SKIP_DEBUG);
    byte[] b = cw.toByteArray();
    fis.close();
    // ...and write class file back
    FileOutputStream fos = new FileOutputStream(args[0]);
    fos.write(b);
    fos.close();
  }
}
Für alle Dateien in einem .jar bzw. .zip Archiv, brauchst du nur über alle .zip-Einträge zu iterieren und ein neues .zip zu bauen.
 

inflamer

Bekanntes Mitglied
Super, vielen Dank, das lässt sich dann wohl sogar recht einfach (über Input-/OutputStream) in mein obiges Script einbauen!

Habe lange danach gesucht...
 

Ähnliche Java Themen

Neue Themen


Oben