Support for signature polymorphic methods
Java class file shrinker, optimizer, obfuscator, and preverifier
Brought to you by:
guardsquare
ProGuard doesn't seem to handle "signature polymorphic" methods properly.
The jvm specs (Java SE 7 and 8 Editions) describes "signature polymorphic" methods (§2.9). During method resolution (§5.4.3.3) " If [the class] declares exactly one method with the name specified by the method reference, and the declaration is a signature polymorphic method (§2.9), then method lookup succeeds."
How to reproduce:
$ cat Test.java public class Test { public void foo(java.lang.invoke.MethodHandle m) throws Throwable { m.invokeExact(1,2,3); } } $ java -version openjdk version "1.8.0_11" OpenJDK Runtime Environment (build 1.8.0_11-b12) OpenJDK 64-Bit Server VM (build 25.11-b02, mixed mode) $ javac Test.java $ java -jar proguard-5.0.jar -injar Test.class -libraryjar rt.jar ProGuard, version 5.0 Reading program directory [Test.class] Reading library jar [rt.jar] Warning: Test: can't find referenced method 'void invokeExact(int,int,int)' in library class java.lang.invoke.MethodHandle Warning: there were 1 unresolved references to library class members. You probably need to update the library versions. (http://proguard.sourceforge.net/manual/troubleshooting.html#unresolvedlibraryclassmember)
Error: Please correct the above warnings first.
Thanks for the concise report. ProGuard currently doesn't treat MethodHandle#invoke/invokeExact differently from regular methods, so you'll see this warning. As you probably know, it is generally not possible to figure out to which method or methods the invocation should be linked, with static analysis and even with dynamic analysis. Dynamic invocations are a real pain for static analysis and optimizations. The warning can help as a reminder that you may need to preserve the targeted methods with this given signature. In the extreme, you could preserve all matching methods, e.g. in this case:
You can suppress the warning with
ProGuard should probably provide a more accurate warning for this particular case. I'll consider it. Your thoughts are welcome.
Indeed, don't think that making a note for each method that matches the signature can scale very well but a customized warning mentioning the signature that is used would definitely help.
Thank you for the quick answer.
A more severe issue is that the types in the signature that is used at the invoke point of the signature polymorphic method are not rewritten/obfuscated properly.
Another issue going on here is that ProGuard is calling this a "warning", but then failing. I'm pretty sure that it's misunderstanding the meaning of "warning".
ProGuard has three types of messages: notes, warnings, and errors. Notes are suggestions, e.g. about probable typos. Errors are fatal problems, e.g. I/O errors. Warnings are the class of problems inbetween, e.g. missing dependencies. A compiler would fail on them, but with ProGuard you can suppress them with -ignorewarnings or -dontwarn.