Proguard is putting “throw null” at the end of many of my methods which is making the resultant jar file unusable.
As context, my company has used Proguard for years, going back to 5.3.1. I was asked to use it on a new Java desktop project that uses post-Java 8 features so I cloned the repo and built the latest. I am compiling with a JDK 15 compiler from AdoptJDK. I made some minor changes to the “.pro” script we had successfully used on other projects, ran the result and got a null pointer exception. I then tried the “application.pro” example from the repo (with the same minor requisite tailoring) with the same results.
One of the classes throwing this exception uses a factory pattern to manage a singleton:
public class Foo{
private static Foo theInstance;
public static void initialize(){
System.out.println("Foo.initialize");
theInstance = new Foo();
System.out.println("Foo.initialize: about to call loadProperties");
loadProperties();
System.out.println("Foo.initialize: after calling loadProperties");
}
public Foo(){
}
public static boolean loadProperties(){
// reads various properties files
...
}
}
The null pointer exception happens in the Foo constructor. The decomplied obfuscated code looks like this:
public final class f{
private static f a;
public static void a() {
System.out.println("Foo.initialize");
new f;
throw null;
}
private f() {
Object var10001 = null;
throw null;
}
}
Note that the second two print statements are missing as, apparently, is the call to loadProperties.
There is more to this class: the original has some 50 methods, the obfuscated has five (none of which is loadProperties according to the out.map that was generated). This is true whether inlining is enabled or not. (I disabled it using
-optimizations !method/inlining/*
as suggested in this post:
java.lang.VerifyError: Bad type on operand stack uninitializedThis · Issue #63 · Guardsquare/proguard · GitHub
)
An almost identical copy of this class used in a prior project with the “.pro” file I started from is handled properly (methods are maintained, print statements are fully present, etc.).
In fact most classes appear to have lost most of their methods. Again, this is true even when I take the application.pro example and make what seem like innocuous (and essential) changes:
-
change the in and out jar variables,
-
add reference to the directory with the required libraries
-libraryjars dist/lib -
explicitly specify the Java modules required
-libraryjars jdk15/jmods/java.base.jmod
-libraryjars jdk15/jmods/java.desktop.jmod
There are several other classes where “throw null” is tagged on as the last statement in multiple methods.
Any insights would be wonderful.