Library interface with generics fails
Java class file shrinker, optimizer, obfuscator, and preverifier
Brought to you by:
guardsquare
Hi,
proguard does not recognize interface with gererics in a library. It's implementation method names are then changed.
Attached is a test project.
This interface is in library.jar
public interface MyInterface<T> {
void setTypedSomething(T var1);
T getTypedSomething();
void normalMethod();
}
Implementation class is in in.jar
public class MyImplFail implements MyInterface<MyPojo> {
MyPojo myPojo;
public MyImplFail() {
}
public void setTypedSomething(MyPojo myPojo) {
this.myPojo = myPojo;
}
public MyPojo getTypedSomething() {
return this.myPojo;
}
public void normalMethod() {
this.myPojo = null;
}
}
Proguard result
public final class a implements MyInterface<c> {
private c a;
public a() {
}
private void a(c var1) {
this.a = var1;
}
private c a() {
return this.a;
}
public final void normalMethod() {
this.a = null;
}
}
The problem is the generics. If your implementation uses <object> as a parameter then Proguard works.
public final class b implements MyInterface<Object> {
private c a;
public b() {
}
public final void setTypedSomething(Object var1) {
this.a = (c)var1;
}
public final Object getTypedSomething() {
return this.a;
}
public final void normalMethod() {
this.a = null;
}
}
Thank you,
Martin
Thanks for your report and test project. The behavior looks correct to me -- how does the problem manifest itself? The name of program class MyPojo is obfuscated to c, and all code is adapted consistently. If you want to prerserve its name (for some external reason), you can specify
-keep class MyPojo.Hi @lafortune,
the problem is that methods setTypedSomethingand getTypedSomething got renamed. in implementation.
The interface is in library jar and therefore we can't rename the implementation methods, right?
notice that it works fine for method normalMethod.
Hi @lafortune,
let me give you an example with a main method.
This code produces output "done" to stdout.
Now this class obfuscated is:
I get the following error
If you want to use the processed jar as a library, you have to keep its public API:
(see the ProGuard manual > Examples > A typical library)
Do you have a different use case?
The Java compiler creates two versions of these methods: one with Object and one with the actual type for T.
hi @lafortune the library jar is not processed at all.
the bug here is that proguard doesn't evaluate T.
In the given example proguard should create the version of the method with MyPojo but it doesn't