views:

179

answers:

3

I have a .jar file which is 1MB. Without debug info, it should be about 100KB. Now, how do I strip the debug info?

Oldtimers from the borland world might remember of a tool called tdstrip which would remove the symbol info from an .exe.

What is the equivalent in the Java world? I'm trying to do mobile development where a 1MB file is way too big.

I know that I could recompile and rebuild the .jar file without the debug info, but if you don't have sources, etc, how do you go about doing it?

+1  A: 

When deploying in the mobile world, it is pretty common to run the entire jar file through some obfuscation tool.

The primary use of this is not to make decompilation harder, but to greatly reduce the size of the jar.

Obfuscation tools already implement many steps that reduce the size of your jar:

  • shortening all stored identifiers to as little as possible
  • stripping all debug information and non-essential attributes
  • possibly even rewriting bytecode to use less space
Joachim Sauer
+1  A: 

Proguard has options for shrinking bytecode.

Mark
+4  A: 

Use %JAVA_HOME%/bin/pack200 -r -G jartostrip.jar

Usage:  pack200 [-opt... | --option=value]... x.pack[.gz] y.jar

Packing Options
  -g, --no-gzip                   output a plain *.pack file with no zipping
  --gzip                          (default) post-process the pack output with gzip
  -G, --strip-debug               remove debugging attributes while packing
  -O, --no-keep-file-order        do not transmit file ordering information
  --keep-file-order               (default) preserve input file ordering
  -S{N}, --segment-limit={N}      output segment limit (default N=1Mb)
  -E{N}, --effort={N}             packing effort (default N=5)
  -H{h}, --deflate-hint={h}       transmit deflate hint: true, false, or keep (default)
  -m{V}, --modification-time={V}  transmit modtimes: latest or keep (default)
  -P{F}, --pass-file={F}          transmit the given input element(s) uncompressed
  -U{a}, --unknown-attribute={a}  unknown attribute action: error, strip, or pass (default)
  -C{N}={L}, --class-attribute={N}={L}  (user-defined attribute)
  -F{N}={L}, --field-attribute={N}={L}  (user-defined attribute)
  -M{N}={L}, --method-attribute={N}={L} (user-defined attribute)
  -D{N}={L}, --code-attribute={N}={L}   (user-defined attribute)
  -f{F}, --config-file={F}        read file F for Pack200.Packer properties
  -v, --verbose                   increase program verbosity
  -q, --quiet                     set verbosity to lowest level
  -l{F}, --log-file={F}           output to the given log file, or '-' for System.out
  -?, -h, --help                  print this message
  -V, --version                   print program version
  -J{X}                           pass option X to underlying Java VM

Notes:
  The -P, -C, -F, -M, and -D options accumulate.
  Example attribute definition:  -C SourceFile=RUH .
  Config. file properties are defined by the Pack200 API.
  For meaning of -S, -E, -H-, -m, -U values, see Pack200 API.
  Layout definitions (like RUH) are defined by JSR 200.

Repacking mode updates the JAR file with a pack/unpack cycle:
    pack200 [-r|--repack] [-opt | --option=value]... [repackedy.jar] y.jar
stacker
Actually, doing this increased the size from 1,082,391 to 1,094,056 bytes!!
anjanb
Curious, did you look at the difference between before and after inside the jar?
PSpeed
In my test the filesize was reduced by 20%, maybe your oringal file was compressed with a higher rate (-E option), try to compress more agressivly. See also: http://java.sun.com/j2se/1.5.0/docs/tooldocs/share/pack200.html
stacker
@anjanb Are you sure that your jar still contains debug symbols?
stacker