Proguard referenced field not found - gradle

I'm trying to use proguard with my gradle project, however, there is a problem with one of my library classes:
The error:
Warning:com.example.MediaView: can't find referenced field 'android.content.Context mContext' in program class com.example.MediaView
In my proguard.txt there are entries required for android apps:
-keepclasseswithmembernames class * {
public <init>(android.content.Context);
}
-keepclasseswithmembernames class * {
public <init>(android.content.Context, android.util.AttributeSet);
}
-keepclasseswithmembernames class * {
public <init>(android.content.Context, android.util.AttributeSet, int);
}
-keep class com.example.MediaView
Also the com.example.MediaView comes from a library, and it extends android.widget.FrameLayout
Any idea how to get rid of this warning? (beside the -dontwarn toggle)
Thanks in advance!

Related

How to keep enums working with proguard enabled?

I have developed an android application that uses Enums in many modules. Now i am trying to protect my application from reverse engineering, for this purpose i have enabled proguard in my application but the issue is after enabling proguard my application crashes wherever i have used Enums.
I have created the following class to define all enums
package app.mypackagename.utils;
import android.content.Context;
public class EnumUtils {
public static enum AppDomain {
LIVE, STAGING, MOCK
}
public static enum UserRole {
CUSTOMER, ADMIN;
}
public static enum Module {
REGISTRATION, PRODUCT
}
}
Enum "UserRole" is being used inside a model class "User"
package app.mypackagename.flavors.models;
import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;
import app.mypackagename.utils.EnumUtils;
public class User {
#SerializedName("sulLevelcode")
public String sulLevelcode;
public EnumUtils.UserRole userRole = null;
}
On successful login i am checking the user role using following code
Gson gson = new Gson();
Type listType = new TypeToken<User>() {
}.getType();
onlineUser = ((User) gson.fromJson(taskItem.getRawResponse(),
listType));
onlineUser.userID = userId;
if (onlineUser.sulLevelcode.equalsIgnoreCase(Constants.LEVEL_CODE_CUSTOMER)) {
onlineUser.userRole = EnumUtils.UserRole.CUSTOMER;
}
But applications always crashes on accessing Enum value.
Below is the crash trace
java.lang.AssertionError: java.lang.NoSuchFieldException: CUSTOMER
at b.b.c.b.a.ja$a.<init>(:808)
at b.b.c.b.a.V.a(:834)
at b.b.c.p.a(:423)
at b.b.c.b.a.p.a(:115)
at b.b.c.b.a.p.a(:164)
at b.b.c.b.a.p.a(:100)
at b.b.c.p.a(:423)
at b.b.c.p.a(:886)
at b.b.c.p.a(:852)
at b.b.c.p.a(:801)
at app.mypackagename.activities.k.a(:355)
at app.mypackagename.f.c.a(:442)
at app.mypackagename.f.c.a(:43)
at app.mypackagename.f.b.a(:288)
at app.mypackagename.f.b.a(:271)
at b.c.a.b.m.c(:107)
at b.c.a.b.m.b(:141)
at b.c.a.b.m.a(:128)
at b.c.b.A.a(:456)
at b.c.a.b.m.c(:107)
at b.c.a.b.m.b(:141)
at b.c.a.b.m.a(:128)
at b.c.b.r.run(:246)
at b.c.a.y$d.run(:60)
at android.os.Handler.handleCallback(Handler.java:761)
at android.os.Handler.dispatchMessage(Handler.java:98)
at android.os.Looper.loop(Looper.java:156)
at android.app.ActivityThread.main(ActivityThread.java:6577)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:986)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:876)
Caused by: java.lang.NoSuchFieldException: CUSTOMER
at java.lang.Class.getField(Class.java:1549)
at b.b.c.b.a.ja$a.<init>(:797)
at b.b.c.b.a.V.a(:834) 
at b.b.c.p.a(:423) 
at b.b.c.b.a.p.a(:115) 
at b.b.c.b.a.p.a(:164) 
at b.b.c.b.a.p.a(:100) 
at b.b.c.p.a(:423) 
at b.b.c.p.a(:886) 
at b.b.c.p.a(:852) 
at b.b.c.p.a(:801) 
at app.mypackagename.activities.k.a(:355) 
at app.mypackagename.f.c.a(:442) 
at app.mypackagename.f.c.a(:43) 
at app.mypackagename.f.b.a(:288) 
at app.mypackagename.f.b.a(:271) 
at b.c.a.b.m.c(:107) 
at b.c.a.b.m.b(:141) 
at b.c.a.b.m.a(:128) 
at b.c.b.A.a(:456) 
at b.c.a.b.m.c(:107) 
at b.c.a.b.m.b(:141) 
at b.c.a.b.m.a(:128) 
at b.c.b.r.run(:246) 
at b.c.a.y$d.run(:60) 
at android.os.Handler.handleCallback(Handler.java:761) 
at android.os.Handler.dispatchMessage(Handler.java:98) 
at android.os.Looper.loop(Looper.java:156) 
at android.app.ActivityThread.main(ActivityThread.java:6577) 
at java.lang.reflect.Method.invoke(Native Method) 
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:986) 
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:876)  
Below is my proguard rules file
# Add project specific ProGuard rules here.
# You can control the set of applied configuration files using the
# proguardFiles setting in build.gradle.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html
# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
# public *;
#}
# Uncomment this to preserve the line number information for
# debugging stack traces.
#-keepattributes SourceFile,LineNumberTable
# If you keep the line number information, uncomment this to
# hide the original source file name.
#-renamesourcefileattribute SourceFile
-dontwarn com.alcorlink.**
-dontwarn com.google.android.**
-dontwarn androidx.media.**
-keepclassmembers enum * {
public static **[] values();
public static ** valueOf(java.lang.String);
}
-keep class app.app.mypackagename.utils.EnumUtils { *; }
##---------------Begin: proguard configuration for Gson ----------
# Gson uses generic type information stored in a class file when working with fields. Proguard
# removes such information by default, so configure it to keep all of it.
-keepattributes Signature
# For using GSON #Expose annotation
-keepattributes *Annotation*
# Gson specific classes
-dontwarn sun.misc.**
#-keep class com.google.gson.stream.** { *; }
# Application classes that will be serialized/deserialized over Gson
-keep class app.mypackagename.flavors.models.User.** { <fields>; }
# Prevent proguard from stripping interface information from TypeAdapterFactory,
# JsonSerializer, JsonDeserializer instances (so they can be used in #JsonAdapter)
-keep class * implements com.google.gson.TypeAdapterFactory
-keep class * implements com.google.gson.JsonSerializer
-keep class * implements com.google.gson.JsonDeserializer
# Prevent R8 from leaving Data object members always null
-keepclassmembers,allowobfuscation class * {
#com.google.gson.annotations.SerializedName <fields>;
}
##---------------End: proguard configuration for Gson ----------
I have tried almost every solution available on Stack Overflow but i am unable to solve this issue.
Some from the ways i tried
--keep class app.mypackagename.utils.EnumUtils{ *; }
-keep class app.mypackagename.flavors.models.User.** { *; }
-keepclassmembers enum * {
public static **[] values();
public static ** valueOf(java.lang.String);
}
-keepclassmembers enum * { *; }
-keepclassmembers enum app.mypackagename.** { *; }
-keepclassmembers enum * {
public static **[] values();
public static ** valueOf(java.lang.String);
}
-keep public enum app.mypackagename.utils.EnumUtils** {
**[] $VALUES;
public *;
}
-keepattributes AppDomain
-keepattributes UserRole
Can somebody please help me out with this. Any help will be appreciated.
I had the same issue, but adding this line to my proguard-rules.pro worked -
-keep class app.mypackagename.constants.* { <fields>; }.
where "app.mypackagename.constants" is the package where all my enums are located.

Xamarin Android Binding incorrect method override name

Quite a strange problem in Xamarin.Android bindings. I have a java class defined as follows:
// Java world
public abstract class BaseRenderableSeries<TX extends Comparable<TX>,
TY extends Comparable<TY>,
TRenderPassData extends ISeriesRenderPassData,
TDataSeries extends IDataSeries<TX, TY>>
implements IRenderableSeries {
// ...
protected abstract IHitProvider<? super TRenderPassData> getHitProvider();
// ...
}
Derived classes in Java override getHitProvider as follows:
public class FastLineRenderableSeries<TX extends Comparable<TX>, TY extends Comparable<TY>> extends XyRenderableSeriesBase<TX, TY, LineRenderPassData> {
#Override
protected IHitProvider<? super LineRenderPassData> getHitProvider() {
return new CompositeHitProvider<>(
new PointMarkerHitProvider(),
new LineHitProvider());
}
}
In Xamarin.Android the binding is generated like this:
// Generated C# Binding in BaseRenderableSeries.cs
//
protected abstract global::Com.Scichart.Charting.Visuals.RenderableSeries.HitTest.IHitProvider RawHitProvider {
// Metadata.xml XPath method reference: path="/api/package[#name='com.scichart.charting.visuals.renderableSeries']/class[#name='BaseRenderableSeries']/method[#name='getHitProvider' and count(parameter)=0]"
[Register ("getHitProvider", "()Lcom/scichart/charting/visuals/renderableSeries/hitTest/IHitProvider;", "GetGetHitProviderHandler")] get;
}
Que? The property has been renamed from HitProvider to RawHitProvider. Derived classes of BaseRenderableSeries are trying to override HitProvider though and this is causing a build error.
// Generated bindings in FastLineRenderableSeries.cs
protected override unsafe global::Com.Scichart.Charting.Visuals.RenderableSeries.HitTest.IHitProvider HitProvider {
// Metadata.xml XPath method reference: path="/api/package[#name='com.scichart.charting.visuals.renderableSeries']/class[#name='FastLineRenderableSeries']/method[#name='getHitProvider' and count(parameter)=0]"
[Register ("getHitProvider", "()Lcom/scichart/charting/visuals/renderableSeries/hitTest/IHitProvider;", "GetGetHitProviderHandler")]
get {
// ...
}
}
}
FastLineRenderableSeries.HitProvider: no suitable method to override
Any idea why? What's Xamarin doing here and how can I prevent its craziness?
That's because generics aren't supported. Maybe there is a possible name conflict wich the generator tries to avoid.
Option a)
Try to change the name of the Property in the base class
<attr path="/api/package[#name='com.scichart.charting.visuals.renderableSeries']/class‌​[#name='BaseRenderableSeries']/method[#name='getHitProvider' and count(parameter)=0]"
name="managedName">HitProvider</attr>
Option b)
Change the name of the Property in the child classes
<attr path="/api/package[#name='com.scichart.charting.visuals.renderableSeries']/class[#name='FastLineRenderableSeries']/method[#name='getHitProvider' and count(parameter)=0]"
name="managedName">RawHitProvider</attr>

BrightCove Video Player not working on Android

java.lang.RuntimeException: A Component requires the 'com.brightcove.player.event.Emits' annotation. If you wish to not listen or emit, create the corresponding annotation with an empty events list.
Has any one else face the same issue??
any help will be appreciable.
It sounds like you do not have the annotation
#Emits(events = {})
before your class declaration. If you show us the relevant fragment it might be obvious to someone what the problem is. A component that emits no events and listens for no events would look like,
/**
* Provides a Component object that is not very useful.
*/
#Emits(events = {})
#ListensFor(events = {})
public class NotVeryUsefulComponent extends AbstractComponent {
}
Please update the proguard with the following lines
-keep public class com.brightcove.player.** { public *;}
-keepclassmembers public class com.brightcove.player.** { public *;}
-keepclasseswithmembers public class com.brightcove.player.** { public *;}
-keep class com.google.android.exoplayer.** { *;}
If you are not using the exoplayer, omit the last line
Your proguard configuration is stripping out the annotations. As an example, please see the proguard-project.txt in our samples repo:
https://github.com/BrightcoveOS/android-player-samples/blob/master/proguard-project.txt

Can the Parse jar be reduced to have fewer methods?

Because of the Android 64k max method limit, I'm trying to reduce the number of methods provided by the Parse Android SDK. Parse-1.5.0.jar has some 4,500+ methods. Any suggestions?
Removing the SDK and using the REST APIs is a possibility, but may be somewhat time consuming.
Try using ProGuard and leave out the idea of using REST APIs... Honestly I never heard about such a workaround for such a problem 0_o
Just tell ProGuard to shrink your code, skipping additional features like obuscation if you don't want to slow down the deploy. The proguard-project.txt file will be more or less like this:
-dontoptimize
-dontobfuscate
-allowaccessmodification
-dontpreverify
# The remainder of this file is identical to the non-optimized version
# of the Proguard configuration file (except that the other file has
# flags to turn off optimization).
-dontusemixedcaseclassnames
-dontskipnonpubliclibraryclasses
-verbose
-keep public class com.google.vending.licensing.ILicensingService
-keep public class com.android.vending.licensing.ILicensingService
# For native methods, see http://proguard.sourceforge.net/manual/examples.html#native
-keepclasseswithmembernames class * {
native <methods>;
}
# keep setters in Views so that animations can still work.
# see http://proguard.sourceforge.net/manual/examples.html#beans
-keepclassmembers public class * extends android.view.View {
void set*(***);
*** get*();
}
# We want to keep methods in Activity that could be used in the XML attribute onClick
-keepclassmembers class * extends android.app.Activity {
public void *(android.view.View);
}
# For enumeration classes, see http://proguard.sourceforge.net/manual/examples.html#enumerations
-keepclassmembers enum * {
public static **[] values();
public static ** valueOf(java.lang.String);
}
-keep class * implements android.os.Parcelable {
public static final android.os.Parcelable$Creator *;
}
-keepclassmembers class **.R$* {
public static <fields>;
}
# The support library contains references to newer platform versions.
# Don't warn about those in case this app is linking against an older
# platform version. We know about them, and they are safe.
-dontwarn android.support.**

android using proguard, stack trace?

I tested my app, and in the emulator and on my device it is working without errors.
I export my eclipse-project with proguard option enabled.
The resulting apk is crashing when I open a custom dialog http://code.google.com/p/dateslider/.
I tried the -keep options for all the classes I used, but no result.
From what I have read, is that I need the trace of the crash., to debug.
Where is it?, only a dialog is shown telling me that the app has crashed.
Jos
EDIT
Thanks to Sean's suggestions I narrow it down to a call of the method "SetContentView". It tried to load data from a layout.
<?xml version="1.0" encoding="utf-8"?>
<nl.zonneveld.pldkal_free.SliderContainer
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res/nl.zonneveld.pldkal_free"
android:id="#+id/dateSliderContainer"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<nl.zonneveld.pldkal_free.ScrollLayout
style="#style/Scroller"
app:labelerClass="nl.zonneveld.pldkal_free.YearLabeler"
app:labelerFormat="%tY"
app:childWidth="150dp"/>
<nl.zonneveld.pldkal_free.ScrollLayout
style="#style/Scroller"
app:labelerClass="nl.zonneveld.pldkal_free.MonthLabeler"
app:labelerFormat="%tB"
app:childWidth="200dp"/>
<include layout="#layout/dialogbuttons"/>
</nl.zonneveld.pldkal_free.SliderContainer>
EDIT
The uknown exception is triggered at
Class<?> klazz = Class.forName(className);
Constructor<?> ctor = klazz.getConstructor(String.class);
className="nl.zonneveld.pldkal_free.YearLabeler".
constructor of YearLabeler:
public YearLabeler(String formatString)
I tried the folowing proguard options, no succes.
-keep public class * extends nl.zonneveld.pldkal_free.YearLabeler{
public <init>(java.lang.String);
}
-keep public class * extends nl.zonneveld.pldkal_free.MonthLabeler{
public <init>(java.lang.String);
}
-keep public class * extends nl.zonneveld.pldkal_free.Labeler{
public <init>(int, int);
}
What is the error -- ClassNotFoundError? Meaning, you think Proguard optimized away that class? You can test that easily by setting -dontshrink, to start. If that doesn't fix it, Proguard isn't the problem.
You can obtain all log output with adb logcat on the command line. There's probably an equivalent for the Eclipse-integrated tools, but I don't know what it is. You can also use the aLogcat app on Android to see the logs.
After a lot of digging, this was the solution. Thanks Sean for the suggestions.
-keep public class * extends nl.zonneveld.pldkal_free.YearLabeler
-keepclassmembers class nl.zonneveld.pldkal_free.YearLabeler{
public <init>(java.lang.String);
}
-keep public class * extends nl.zonneveld.pldkal_free.MonthLabeler
-keepclassmembers class nl.zonneveld.pldkal_free.MonthLabeler{
public <init>(java.lang.String);
}
-keep public class * extends nl.zonneveld.pldkal_free.Labeler
-keepclassmembers class nl.zonneveld.pldkal_free.Labeler{
public <init>(int, int);
}

Resources