Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

smack for android fails when using proguard

I am using the smack library (4.1.2) in my Android app to connect to an XMPP server. It runs perfectly well when the code is NOT minified (ie with proguard). But in release mode, with proguard enabled, the app crashes as soon as it connects to the server.

I am trying to keep all relevant smack classes unminified as suggested here: What are the recommended ProGuard rules for Smack 4.1?

-keep class org.jivesoftware.smack.** { *; }
-keep class org.jivesoftware.smackx.** { *; }

But for me this doesn't work. Below is the crash stack trace.

 java.lang.ExceptionInInitializerError
  at org.jivesoftware.smackx.privacy.PrivacyListManager.<init>(PrivacyListManager.java:126)
  at org.jivesoftware.smackx.privacy.PrivacyListManager.getInstanceFor(PrivacyListManager.java:210)
  at org.jivesoftware.smackx.privacy.PrivacyListManager$1.connectionCreated(PrivacyListManager.java:81)
  at org.jivesoftware.smack.tcp.XMPPTCPConnection.initConnection(XMPPTCPConnection.java:636)
  at org.jivesoftware.smack.tcp.XMPPTCPConnection.connectInternal(XMPPTCPConnection.java:834)
  at org.jivesoftware.smack.AbstractXMPPConnection.connect(AbstractXMPPConnection.java:365)
  ...
 Caused by: java.lang.ClassCastException: java.lang.Class cannot be cast to java.lang.reflect.ParameterizedType
  at org.jivesoftware.smack.filter.FlexibleStanzaTypeFilter.<init>(FlexibleStanzaTypeFilter.java:40)
  at org.jivesoftware.smackx.privacy.filter.SetActiveListFilter.<init>(SetActiveListFilter.java:27)
  at org.jivesoftware.smackx.privacy.filter.SetActiveListFilter.<clinit>(SetActiveListFilter.java:25)

Any ideas on what proguard config would fix this?

Update: I already referred to the other issue in my report and explained that proposed solution is not a fix in this case.

Update 2: I have regenerated the stack trace with line numbers enabled.

like image 483
Steve Avatar asked Feb 09 '23 17:02

Steve


1 Answers

So, I found a solution. Can't believe I spend a whole day on this problem! Hope this saves someone else the same trouble:

The line causing the problem (in smack library) is

stanzaType = (Class<S>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0];

Note the cast. The problem appears to be the proguard by default looses some information on types, even if you have specified "-keep" for your classes. The crucial bit of helpful information is here: Field.getGenericType() returns instance of java.lang.Class instead of Type

The answer to my question is therefore that the following proguard config is required:

-keepattributes Signature
-keep class org.jivesoftware.smack.** { *; }
-keep class org.jivesoftware.smackx.** { *; }
like image 85
Steve Avatar answered Feb 19 '23 00:02

Steve