Using Proguard 7.1.1 on Gradle 7.2, I have a single .war which includes all my code and libs.
I’m trying to get this to work for more than 1 week now!
My original .war is around 18Mb.
Even with these very liberal rules:
task optimize(type: proguard.gradle.ProGuardTask) {
injars 'build/libs/app.war'
outjars 'build/libs/app_min.war'
forceprocessing
ignorewarnings
libraryjars "${System.getProperty('java.home')}/lib/"
keepattributes '*Annotation*'
keepattributes 'Signature'
keepattributes 'InnerClasses'
keep includedescriptorclasses: true, 'class * { *; }'
keep includedescriptorclasses: true, 'public class * { *; }'
keep includedescriptorclasses: true, 'final class * { *; }'
keep includedescriptorclasses: true, 'abstract class * { *; }'
keep includedescriptorclasses: true, 'interface * { *; }'
keep includedescriptorclasses: true, 'public interface * { *; }'
keep includedescriptorclasses: true, 'final interface * { *; }'
keep includedescriptorclasses: true, 'abstract interface * { *; }'
keep includedescriptorclasses: true, 'enum * { *; }'
keep includedescriptorclasses: true, 'public enum * { *; }'
keep includedescriptorclasses: true, 'final enum * { *; }'
keep includedescriptorclasses: true, 'abstract enum * { *; }'
// Preserve all public applications.
keepclasseswithmembers 'public class * { \
public static void main(java.lang.String[]); \
}'
// Preserve all public servlets.
keep 'public class * implements javax.servlet.Servlet'
// Preserve all public servlets.
keep 'public class * extends HttpServlet'
// Preserve all native method names and the names of their classes.
keepclasseswithmembernames includedescriptorclasses: true, 'class * { \
native <methods>; \
}'
// Preserve the special static methods that are required in all enumeration
// classes.
keepclassmembers allowoptimization: true, 'enum * { \
public static **[] values(); \
public static ** valueOf(java.lang.String); \
}'
// Explicitly preserve all serialization members. The Serializable interface
// is only a marker interface, so it wouldn't save them.
// You can comment this out if your library doesn't use serialization.
// If your code contains serializable classes that have to be backward
// compatible, please refer to the manual.
keepclassmembers 'class * implements java.io.Serializable { \
static final long serialVersionUID; \
static final java.io.ObjectStreamField[] serialPersistentFields; \
private void writeObject(java.io.ObjectOutputStream); \
private void readObject(java.io.ObjectInputStream); \
java.lang.Object writeReplace(); \
java.lang.Object readResolve(); \
}'
}
My code execution fails with:
SEVERE:
java.lang.ExceptionInInitializerError
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:348)
at oracle.ucp.util.Util.getClassForName(Unknown Source)
at oracle.ucp.jdbc.PoolDataSourceImpl.initConnectionFactory(Unknown Source)
at oracle.ucp.jdbc.PoolDataSourceImpl.createUniversalConnectionPool(Unknown Source)
at oracle.ucp.admin.UniversalConnectionPoolManagerBase.createConnectionPool(Unknown Source)
The generated output is 14Mb so Proguard is still removing something.
Update
If I add dontobfuscate my code works, but it genereates a 17.5Mb .war file, so almost no gain.
Strangely, if I add the allowobfuscation: false to the keep clauses:
keep includedescriptorclasses: true, allowobfuscation: false, 'class * { *; }'
keep includedescriptorclasses: true, allowobfuscation: false, 'public class * { *; }'
keep includedescriptorclasses: true, allowobfuscation: false, 'final class * { *; }'
keep includedescriptorclasses: true, allowobfuscation: false, 'abstract class * { *; }'
keep includedescriptorclasses: true, allowobfuscation: false, 'interface * { *; }'
keep includedescriptorclasses: true, allowobfuscation: false, 'public interface * { *; }'
keep includedescriptorclasses: true, allowobfuscation: false, 'final interface * { *; }'
keep includedescriptorclasses: true, allowobfuscation: false, 'abstract interface * { *; }'
keep includedescriptorclasses: true, allowobfuscation: false, 'enum * { *; }'
keep includedescriptorclasses: true, allowobfuscation: false, 'public enum * { *; }'
keep includedescriptorclasses: true, allowobfuscation: false, 'final enum * { *; }'
keep includedescriptorclasses: true, allowobfuscation: false, 'abstract enum * { *; }'
It still obfuscates some things, like local function variables and generates a 14.5Mb .war, so maybe there’s a bug, because I think it should not obfuscate.