Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Proguard issue with SAAgent(Samsung Accessory) java.lang.NoSuchMethodException: <init> []

I am trying to use proguard with my android app and am using the samsung accesory sdk which keeps giving be trouble.

No matter what I try in the proguard configuration I can't seem to get past this runtime exception:

07-21 13:44:12.851: E/SAAgent(3563): <init> []

07-21 13:44:12.851: E/SAAgent(3563): java.lang.NoSuchMethodException: <init> []

...

07-21 13:44:12.851: E/AndroidRuntime(3563): Caused by: java.lang.RuntimeException: Invalid implemetation of SASocket. Provider a public default constructor.

...

Does anyone have any idea on what to try?

like image 923
user3861893 Avatar asked Jul 21 '14 18:07

user3861893


1 Answers

The problem is that, with some optimization turned on, Proguard will change every inner class in a top-level class.

This means that the default constructor of the inner class will be exchanged with an one-parameter constructor which takes the instance of the outer class, because in java an inner class keeps a reference to the outer class.

The Samsung Accesory SDK requires a default constructor for the SASocket inner class implementation because I guess they use reflection to instantiate that object.

Here http://sourceforge.net/p/proguard/bugs/387/ you can read that: "Outer$Inner is not changed to a top-level class, unless you also add -repackageclasses and -allowaccessmodification to the configuration".

Unfortunately those flags are inherited usually from proguard-android-optimize.txt and if you want to keep the optimization on, the solution is adding to your proguard config:

-keepattributes InnerClasses

Please, notice, that in order to be able to use the whole functions of the Samsung Accesory SDK you should also include the following rules:

# Based on http://proguard.sourceforge.net/manual/examples.html#library 

-keep public class com.samsung.** { 
    public protected *; 
}   

-keepclassmembernames class com.samsung.** {    
    java.lang.Class class$(java.lang.String);   
    java.lang.Class class$(java.lang.String, boolean);  
}   

-keepclasseswithmembernames class com.samsung.** {  
    native <methods>;   
}   

-keepclassmembers enum com.samsung.** { 
    public static **[] values();    
    public static ** valueOf(java.lang.String); 
}   

-keepclassmembers class com.samsung.** implements java.io.Serializable {    
    static final long serialVersionUID; 
    private 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(); 
}
like image 145
Luigi Massa Gallerano Avatar answered Oct 14 '22 08:10

Luigi Massa Gallerano