Proguard breaks program even after keeping everything

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.