I use a library called iText to write new information to existing PDFs. In order to encrypt PDFs, iText (for Android) uses a library called SpongyCastle which is an Android port of BouncyCastle. Unfortunately, both iText and Spongycastle contain a very large number of methods (15k+). In Android there is a hard limit to the number of methods you can use (64k). Fortunately, iText does not use many classes in the Spongycastle jar.
I was able to unzip the Spongycastle jar and remove all of the classes that iText does not use and rezip the file.
Everything works great until I run proguard in a maven build to produce a final apk. I get the below IOException that doesn't make sense to me.
Your help in resolving this error would be very much appreciated.
Thank you in advance. I've also included the portion of the proguard.cfg that references bouncycastle.
-keep class org.bouncycastle.crypto.** {*;}
[DEBUG] Reading program jar [.m2/repository/com/madgag/sc-light-jdk15on/1.47.0.2/sc-light-jdk15on-1.47.0.2-reduced.jar] (filtered)
[INFO] Warning: class [spongycastleseriouslyreduced/org/spongycastle/asn1/ASN1InputStream.class] unexpectedly contains class [org.spongycastle.asn1.ASN1InputStream]
[INFO] Warning: class [spongycastleseriouslyreduced/org/spongycastle/asn1/DEROutputStream.class] unexpectedly contains class [org.spongycastle.asn1.DEROutputStream]
[INFO] Warning: class [spongycastleseriouslyreduced/org/spongycastle/crypto/BlockCipher.class] unexpectedly contains class [org.spongycastle.crypto.BlockCipher]
[INFO] java.io.IOException: Can't read [.m2/repository/com/madgag/sc-light-jdk15on/1.47.0.2/sc-light-jdk15on-1.47.0.2-reduced.jar(;;;;!META-INF/maven/**,!META-INF/MANIFEST.MF)] (Can't process class [__MACOSX/spongycastleseriouslyreduced/org/spongycastle/crypto/._BlockCipher.class] (Invalid magic number [51607] in class))
[INFO] at proguard.InputReader.readInput(InputReader.java:230)
[INFO] at proguard.InputReader.readInput(InputReader.java:200)
[INFO] at proguard.InputReader.readInput(InputReader.java:178)
[INFO] at proguard.InputReader.execute(InputReader.java:78)
[INFO] at proguard.ProGuard.readInput(ProGuard.java:196)
[INFO] at proguard.ProGuard.execute(ProGuard.java:78)
[INFO] at proguard.ProGuard.main(ProGuard.java:492)
[INFO] Caused by: java.io.IOException: Can't process class [__MACOSX/spongycastleseriouslyreduced/org/spongycastle/crypto/._BlockCipher.class] (Invalid magic number [51607] in class)
[INFO] at proguard.io.ClassReader.read(ClassReader.java:112)
[INFO] at proguard.io.FilteredDataEntryReader.read(FilteredDataEntryReader.java:87)
[INFO] at proguard.io.FilteredDataEntryReader.read(FilteredDataEntryReader.java:87)
[INFO] at proguard.io.JarReader.read(JarReader.java:65)
[INFO] at proguard.io.DirectoryPump.readFiles(DirectoryPump.java:65)
[INFO] at proguard.io.DirectoryPump.pumpDataEntries(DirectoryPump.java:53)
[INFO] at proguard.InputReader.readInput(InputReader.java:226)
[INFO] ... 6 more
[INFO] Caused by: java.lang.UnsupportedOperationException: Invalid magic number [51607] in class
[INFO] at proguard.classfile.util.ClassUtil.checkMagicNumber(ClassUtil.java:47)
[INFO] at proguard.classfile.io.ProgramClassReader.visitProgramClass(ProgramClassReader.java:79)
[INFO] at proguard.classfile.ProgramClass.accept(ProgramClass.java:346)
[INFO] at proguard.io.ClassReader.read(ClassReader.java:91)
[INFO] ... 12 more
The issue is that your re-packaged jar contains
*.class
files which do not start with the correct magic bytes such a file is expected to start with, i.e. 0xCAFEBABE, cf. this wikipedia article.It also names the file in question:
The naming scheme indicates that this indeed is not a
*.class
file at all but instead a metafile added by some Mac zip program. Proguard does not know such Mac specific stuff and, therefore, falls.Thus, when you rezip the file, you have to take care that you do not add such Mac specific stuff. This can be done by e.g. using the Java SDK jar utility or a non-Mac zip utility.