Getting "Note: duplicate definition of library class" Proguard - java

Below is the application.pro which is the configuration to obfuscate the spring related standalone application:
# This ProGuard configuration file illustrates how to process applications.
# Usage:
# java -jar proguard.jar #applications.pro
#
# Specify the input jars, output jars, and library jars.
-injars xyz.jar
-outjars xyz_out.jar
-libraryjars C:\Program Files\Java\jdk1.8.0_20\jre\lib\rt.jar
-libraryjars <LocationOfJar>/xyz.jar
#-libraryjars servlet.jar
#-libraryjars jai_core.jar
#...
# Save the obfuscation mapping to a file, so you can de-obfuscate any stack
# traces later on. Keep a fixed source file attribute and all line number
# tables to get line numbers in the stack traces.
# You can comment this out if you're not interested in stack traces.
-printmapping out.map
-renamesourcefileattribute SourceFile
-keepattributes SourceFile,LineNumberTable
# Preserve all annotations.
-keepattributes *Annotation*
# You can print out the seeds that are matching the keep options below.
#-printseeds out.seeds
# Preserve all public applications.
-keepclasseswithmembers public class * {
public static void main(java.lang.String[]);
}
# Preserve all native method names and the names of their classes.
-keepclasseswithmembernames,includedescriptorclasses class * {
native <methods>;
}
# Preserve the special static methods that are required in all enumeration
# classes.
-keepclassmembers,allowoptimization enum * {
public static **[] values();
public static ** valueOf(java.lang.String);
}
# Explicitly preserve all serialization members. The Serializable interface
# is only a marker interface, so it wouldn't save them.
# You can comment this out if your application doesn't use serialization.
# If your code contains serializable classes that have to be backward
# compatible, please refer to the manual.
-keepclassmembers class * implements java.io.Serializable {
static final long serialVersionUID;
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();
}
# Your application may contain more items that need to be preserved;
# typically classes that are dynamically created using Class.forName:
# -keep public class mypackage.MyClass
# -keep public interface mypackage.MyInterface
# -keep public class * implements mypackage.MyInterface
#Warnings to be removed. Otherwise maven plugin stops, but not dangerous
-keep public class com.sun.xml.internal.**
-keep public class com.sun.istack.internal.**
-keep public class org.codehaus.jackson.**
-keep public class org.springframework.**
-keep public class java.awt.**
-keep public class javax.security.**
-keep public class java.beans.**
-keep public class javax.xml.**
-keep public class java.util.**
-keep public class org.w3c.dom.**
-keep public class com.google.common.**
-keep public class org.apache.**
-keep public class org.xnio.**
-keep public class javax.xml.**
-keep public class java.time.**
-keep public class com.sun.corba.**
-keep public class org.hibernate.**
-keep public class antlr.**
-dontwarn com.sun.xml.internal.**
-dontwarn com.sun.istack.internal.**
-dontwarn org.codehaus.jackson.**
-dontwarn org.springframework.**
-dontwarn java.awt.**
-dontwarn javax.security.**
-dontwarn java.beans.**
-dontwarn javax.xml.**
-dontwarn java.util.**
-dontwarn org.w3c.dom.**
-dontwarn com.google.common.**
-dontwarn org.apache.**
-dontwarn org.xnio.**
-dontwarn javax.xml.**
-dontwarn java.time.**
-dontwarn com.sun.corba.**
-dontwarn org.hibernate.**
-dontwarn antlr.**
-dontskipnonpubliclibraryclasses
When I run:
java -jar proguard.jar #applications.pro
I get this below error:
Note: duplicate definition of library class
And output is not generated as given in the application.pro:
Note: there were 166 classes trying to access generic signatures using reflection.
You should consider keeping the signature attributes
(using '-keepattributes Signature').
(http://proguard.sourceforge.net/manual/troubleshooting.html#attributes)
Note: there were 21 classes trying to access enclosing classes using reflection.
You should consider keeping the inner classes attributes
(using '-keepattributes InnerClasses').
(http://proguard.sourceforge.net/manual/troubleshooting.html#attributes)
Note: there were 5 classes trying to access enclosing methods using reflection.
You should consider keeping the enclosing method attributes
(using '-keepattributes InnerClasses,EnclosingMethod').
(http://proguard.sourceforge.net/manual/troubleshooting.html#attributes)
Note: there were 563 library classes explicitly being kept.
You don't need to keep library classes; they are already left unchanged.
(http://proguard.sourceforge.net/manual/troubleshooting.html#libraryclass)
Note: there were 55 unresolved dynamic references to classes or interfaces.
You should check if you need to specify additional program jars.
(http://proguard.sourceforge.net/manual/troubleshooting.html#dynamicalclass)
Note: there were 4 class casts of dynamically created class instances.
You might consider explicitly keeping the mentioned classes and/or
their implementations (using '-keep').
(http://proguard.sourceforge.net/manual/troubleshooting.html#dynamicalclasscast)
Note: there were 292 accesses to class members by means of introspection.
You should consider explicitly keeping the mentioned class members
(using '-keep' or '-keepclassmembers').
(http://proguard.sourceforge.net/manual/troubleshooting.html#dynamicalclassmember)
Warning: there were 5329 unresolved references to classes or interfaces.
You may need to add missing library jars or update their versions.
If your code works fine without the missing classes, you can suppress
the warnings with '-dontwarn' options.
(http://proguard.sourceforge.net/manual/troubleshooting.html#unresolvedclass)
Warning: there were 117 instances of library classes depending on program classes.
You must avoid such dependencies, since the program classes will
be processed, while the library classes will remain unchanged.
(http://proguard.sourceforge.net/manual/troubleshooting.html#dependency)
Warning: there were 42 unresolved references to program class members.
Your input classes appear to be inconsistent.
You may need to recompile the code.
(http://proguard.sourceforge.net/manual/troubleshooting.html#unresolvedprogramclassmember)
Error: Please correct the above warnings first.
How to resolve this issue?

Related

Why is ProGuard not obfuscating inner classes / enums

I am trying to obfuscate some classes which contain a number of inner enums which I understand are compiled to separate standalone classes with the "$" separator by javac at compile time.
However, the problem I am having is that, although the contents of the enums are obfuscated, the parent / outer class as well as the enum class names themselves as well as their package names are not being obfuscated since the classes themselves are not being obfuscated.
We have specified ProGuard to keep various other classes within our proprietary packages (which are being dealt with correctly), but these should not be affecting the above mentioned classes.
Here is our config.pro file:
-injars .\build\libs\plugin.jar
-outjars .\build\libs\plugin_obfuscated.jar
-libraryjars .\jre\lib\rt.jar
-libraryjars .\jre\lib\jce.jar
-libraryjars .\jre\lib\ext\jfxrt.jar
## Mapping
-classobfuscationdictionary .\config_classnames.pro
-packageobfuscationdictionary .\config_packagenames.pro
-printmapping .\build\libs\proguard_obfuscation_map.txt
-printseeds .\build\libs\proguard_seeds_map.txt
-printusage .\build\libs\proguard_deadusage_map.txt
## Shrinking
-dontshrink
## Optimizations
#-dontoptimize
-optimizations method/removal/parameter,method/inlining/short,
method/inlining/unique
-optimizations code/removal/advanced,code/simplification/string,
code/removal/exception,code/removal/variable,code/merging
-optimizations class/unboxing/enum
-allowaccessmodification
-mergeinterfacesaggressively
#-optimizationpasses 5
#-repackageclasses ''
-flattenpackagehierarchy 'software'
## Obfuscation
-dontusemixedcaseclassnames
-overloadaggressively
## Keep attributes
-keepattributes !InnerClasses,Signature,Deprecated,*Annotation*,Synthetic
-adaptresourcefilecontents **.fxml
# ProGuard doesn't print notes about classes with matching names
-dontnote com.google.**
-dontnote com.sun.**
-dontnote org.apache.log4j.**
-dontnote org.apache.logging.**
-dontnote com.itextpdf.**
-dontnote org.apache.commons.io.**
-dontnote org.apache.commons.codec.**
-dontnote org.apache.commons.lang3.**
-dontnote org.hibernate.**
-dontnote **
-dontwarn **
# Keep specific proprietary classes
-keep class com.mycompany.product.framework.logging.** {
}
-keep class com.mycompany.product.plugin.persistence.** {
<fields>;
<methods>;
}
-keep class com.mycompany.product.plugin.networking.** {
<fields>;
<methods>;
}
-keep class com.mycompany.product.framework.automation.events.** {
<fields>;
<methods>;
}
-keep class com.mycompany.product.plugin.events.** {
<fields>;
<methods>;
}
-keep class com.mycompany.product.plugin.remote.** {
<fields>;
<methods>;
}
-keepnames class com.mycompany.product.plugin.providers.* {
}
-keepclassmembers class com.mycompany.product.framework.events.TestCase
{
<fields>;
<methods>;
}
# Keep class members with #FXML annotations
-keepclassmembers,allowshrinking class * {
#javafx.fxml.FXML
<fields>;
#javafx.fxml.FXML
<methods>;
}
# Keep - Antlr library
-keep class antlr.** {
<fields>;
<methods>;
}
# Keep fasterxml
-keep class com.fasterxml.** {
<fields>;
<methods>;
}
# Keep - Google classes
-keep class com.google.** {
<fields>;
<methods>;
}
... remaining other classes not to be included / sanitized
... followed by standard Proguard template configuration (truncated)
# Keep classes that implement Serializable
-keepnames class * implements java.io.Serializable
-keepclassmembers class * implements java.io.Serializable {
static final long serialVersionUID;
private static final java.io.ObjectStreamField[] serialPersistentFields;
!static !transient <fields>;
private void writeObject(java.io.ObjectOutputStream);
private void readObject(java.io.ObjectInputStream);
java.lang.Object writeReplace();
java.lang.Object readResolve();
}
# Keep - Applications. Keep all application classes, along with their
'main' methods.
-keepclasseswithmembers public class * {
public static void main(java.lang.String[]);
}
# Also keep - Enumerations. Keep the special static methods that are
required in enumeration classes.
-keepclassmembers enum * {
public static **[] values();
public static ** valueOf(java.lang.String);
}
# Keep - Native method names. Keep all native class/method names.
-keepclasseswithmembers,includedescriptorclasses,allowshrinking class * {
native <methods>;
}
The classes we are trying to obfuscate, which include the inner / nested enum classes are under the package:
com.mycompany.packageContainingEnum1.enumOuterClass1
com.mycompany.packageContainingEnum1.enumOuterClass1$enum1ClassName
and
com.mycompany.packageContainingEnum2.enumouterClass2
com.mycompany.packageContainingEnum2.enumOuterClass2$enum2ClassName
As you can see, the packages which are giving the problems are below the "product" package and therefore should not be affected by the rules above?
Any ideas why the enumouterClass2 and enumOuterClass2$enum2ClassName (enum) names are being preserved? This seems strange as by default, most people seem to have trouble preventing obfuscation of inner classes.
Thanks very much for your help.

transformClassesAndResourcesWithProguardForRelease' error in Android

Hi I am struggling to create release version for my project. I have been try lot of things on Progaurd through SO / Google help but I am still not able to create the release version.
Can somebody help me with this? I always get this issue:
Error:Execution failed for task ':app:transformClassesAndResourcesWithProguardForRelease'.
> java.io.IOException: Please correct the above warnings first.
Here is the full detailed error: http://justpaste.it/perror sorry I had to put as a link because it is huge.
Here are dependencies:
//compile fileTree(dir: 'libs', include: ['*.jar'])
testCompile 'junit:junit:4.12'
compile 'com.android.support:appcompat-v7:23.1.1'
compile 'com.android.support:design:23.1.1'
compile 'com.rengwuxian.materialedittext:library:2.1.4'
compile 'com.squareup.picasso:picasso:2.5.2'
compile 'com.nostra13.universalimageloader:universal-image-loader:1.9.4'
compile 'org.apache.httpcomponents:httpcore:4.4.1'
compile 'com.squareup.retrofit:retrofit:1.9.0'
compile 'com.loopj.android:android-async-http:1.4.8'
compile 'com.android.support:cardview-v7:23.1.1'
compile 'com.android.support:recyclerview-v7:23.1.1'
compile project(':pageIndicator')
compile 'com.github.neopixl:PixlUI:v1.0.6'
compile 'com.github.bumptech.glide:glide:3.6.1'
My progaurd file:
# You can edit the include path and order by changing the ProGuard
# include property in project.properties.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html
# Add any project specific keep options here:
# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
-dontwarn com.google.code.**
-dontwarn org.apache.**
-dontwarn jp.wasabeef.recyclerview.**
-dontwarn com.nostra13.universalimageloader.**
-dontwarn org.acra.**
#wasabeef recyclerview
-keep class jp.wasabeef.recyclerview.** { *; }
-keepattributes Signature
#HTTP Legacy
-keep class org.apache.** { *; }
-keepattributes Signature
#Universal Image Loader
-keep class com.nostra13.universalimageloader.** { *; }
-keepattributes Signature
#Acra
-keep class org.acra.** { *; }
-keepattributes Signature
#Support libraries
-keep class com.android.** { *; }
-keepattributes Signature
# Keep the annotations
-keepattributes *Annotation*
-allowaccessmodification
-keepattributes *Annotation*
-renamesourcefileattribute SourceFile
-keepattributes SourceFile,LineNumberTable
-repackageclasses ''
-dontnote com.android.vending.licensing.ILicensingService
# Explicitly preserve all serialization members. The Serializable interface
# is only a marker interface, so it wouldn't save them.
-keepclassmembers class * 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();
}
# Preserve all native method names and the names of their classes.
-keepclasseswithmembernames class * {
native <methods>;
}
-keepclasseswithmembernames class * {
public <init>(android.content.Context, android.util.AttributeSet);
}
-keepclasseswithmembernames class * {
public <init>(android.content.Context, android.util.AttributeSet, int);
}
# Preserve static fields of inner classes of R classes that might be accessed
# through introspection.
-keepclassmembers class **.R$* {
public static <fields>;
}
# Preserve the special static methods that are required in all enumeration classes.
-keepclassmembers enum * {
public static **[] values();
public static ** valueOf(java.lang.String);
}
-keep public class * {
public protected *;
}
-keep class * implements android.os.Parcelable {
public static final android.os.Parcelable$Creator *;
}
-keep class com.splunk.** { *; }
-keep public class * extends android.app.Activity
-keep public class * extends android.app.Application
-keep public class * extends android.app.Service
-keep public class * extends android.content.BroadcastReceiver
-keep public class * extends android.content.ContentProvider
-keep public class * extends android.app.backup.BackupAgentHelper
-keep public class * extends android.preference.Preference
-keep public class com.android.vending.licensing.ILicensingService
-keepclasseswithmembernames class * {
native <methods>;
}
-keepclasseswithmembers class * {
public <init>(android.content.Context, android.util.AttributeSet);
}
-keepclasseswithmembers class * {
public <init>(android.content.Context, android.util.AttributeSet, int);
}
-keepclassmembers class * extends android.app.Activity {
public void *(android.view.View);
}
-keepclassmembers enum * {
public static **[] values();
public static ** valueOf(java.lang.String);
}
-keep class * implements android.os.Parcelable {
public static final android.os.Parcelable$Creator *;
}
-keep class com.splunk.** { *; }
-dontwarn rx.**
-dontwarn okio.**
-dontwarn com.squareup.okhttp.**
-keep class com.squareup.okhttp.** { *; }
-keep interface com.squareup.okhttp.** { *; }
-keep class org.apache.http.** { *; }
-dontwarn org.apache.http.**
-dontwarn android.net.**
-dontwarn retrofit.**
-dontwarn retrofit.appengine.UrlFetchClient
-keep class retrofit.** { *; }
-keepclasseswithmembers class * {
#retrofit.http.* <methods>;
}
-keepattributes Signature
-keepattributes *Annotation*
-keep class sun.misc.Unsafe { *; }
#your package path where your gson models are stored
-keep class com.ylg.others.** { *; }
In your ProGuard file add:
-ignorewarnings
like :
# Add project specific ProGuard rules here.
# By default, the flags in this file are appended to flags specified
# in D:\Softwares\Developing\Android\sdk/tools/proguard/proguard-android.txt
# You can edit the include path and order by changing the proguardFiles
# directive in build.gradle.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html
# Add any project specific keep options here:
# 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
-ignorewarnings
You wouldn't have to specify any package like com.viewpagerindicator.** , this will suppress all warnings and the Gradle Console will just say like :
......
Warning: there were 4 unresolved references to classes or interfaces.
You may need to add missing library jars or update their versions.
If your code works fine without the missing classes, you can suppress
the warnings with '-dontwarn' options.
(http://proguard.sourceforge.net/manual/troubleshooting.html#unresolvedclass)
Warning: there were 2 unresolved references to library class members.
You probably need to update the library versions.
(http://proguard.sourceforge.net/manual/troubleshooting.html#unresolvedlibraryclassmember)
Note: you're ignoring all warnings!
Ignoring unused library classes...
Original number of library classes: 4237
Final number of library classes: 1317
Printing kept classes, fields, and methods...
Shrinking...
......
In your ProGuard file add:
-dontwarn com.viewpagerindicator.**
If you open up the link you provided and search for 'Warning' about two thirds down you can see the message:
Warning:com.viewpagerindicator.LinePageIndicator: can't find referenced method 'float ceil(float)' in library class android.util.FloatMath
If there are any warnings ProGuard will stop and ask you to fix them first or if your code works you can choose to ignore them with dontwarn.
Update 05/01/2017
If the warning says in program class it is likely that your compiled class files are inconsistent, try removing them all and and rebuilding your project.
If the warning says in library class your compiled class files are inconsistent with the libraries. Try recompiling the class files or upgrading the libraries to consistent versions.
You can read more here.
What has helped me was to update all dependencies to last version.
In my case, the proguard file was totally ignored because the project consisted of several modules. According to this answer, the solution was to set the following in the gradle of the module causing the problem:
defaultConfig {
consumerProguardFiles 'proguard-rules.txt'
}
This seems to include the proguard of the module in the application's proguard. Now my dontwarn statements are taken in consideration.

ProGuard for Android and GSON

I'm setting up ProGuard for my Android project. My project also uses GSON.
I've researched ProGuard configurations for compatibility with GSON and Android and came across this example offered by google-gson https://code.google.com/p/google-gson/source/browse/trunk/examples/android-proguard-example/proguard.cfg.
ProGuard config copied below:
##---------------Begin: proguard configuration common for all Android apps ----------
-optimizationpasses 5
-dontusemixedcaseclassnames
-dontskipnonpubliclibraryclasses
-dontskipnonpubliclibraryclassmembers
-dontpreverify
-verbose
-dump class_files.txt
-printseeds seeds.txt
-printusage unused.txt
-printmapping mapping.txt
-optimizations !code/simplification/arithmetic,!field/*,!class/merging/*
-allowaccessmodification
-keepattributes *Annotation*
-renamesourcefileattribute SourceFile
-keepattributes SourceFile,LineNumberTable
-repackageclasses ''
-keep public class * extends android.app.Activity
-keep public class * extends android.app.Application
-keep public class * extends android.app.Service
-keep public class * extends android.content.BroadcastReceiver
-keep public class * extends android.content.ContentProvider
-keep public class * extends android.app.backup.BackupAgentHelper
-keep public class * extends android.preference.Preference
-keep public class com.android.vending.licensing.ILicensingService
-dontnote com.android.vending.licensing.ILicensingService
# Explicitly preserve all serialization members. The Serializable interface
# is only a marker interface, so it wouldn't save them.
-keepclassmembers class * 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();
}
# Preserve all native method names and the names of their classes.
-keepclasseswithmembernames class * {
native <methods>;
}
-keepclasseswithmembernames class * {
public <init>(android.content.Context, android.util.AttributeSet);
}
-keepclasseswithmembernames class * {
public <init>(android.content.Context, android.util.AttributeSet, int);
}
# Preserve static fields of inner classes of R classes that might be accessed
# through introspection.
-keepclassmembers class **.R$* {
public static <fields>;
}
# Preserve the special static methods that are required in all enumeration classes.
-keepclassmembers enum * {
public static **[] values();
public static ** valueOf(java.lang.String);
}
-keep public class * {
public protected *;
}
-keep class * implements android.os.Parcelable {
public static final android.os.Parcelable$Creator *;
}
##---------------End: proguard configuration common for all Android apps ----------
##---------------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
-keep class sun.misc.Unsafe { *; }
#-keep class com.google.gson.stream.** { *; }
# Application classes that will be serialized/deserialized over Gson
-keep class com.google.gson.examples.android.model.** { *; }
##---------------End: proguard configuration for Gson ----------
Questions:
I see that this file has not been updated since 2011, is it still recommended for use? I ask because Android/GSON has changed quite a bit since then so I don't know how much of the above in unnecessary or incorrect.
If this is not recommended, is there a new recommended ProGuard configuration for GSON in Android?
I think most of those settings you have there are already included in the Android SDK by default.
So you can remove most of them, just leaving in the section devoted to GSON.
I am developing in Eclipse using Android SDK Tools 22.6.3 & whatever version of ProGuard ships with that.
Here's what I'm using for GSON 2.2.4 (as per their example):
##---------------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
# Gson specific classes
-keep class sun.misc.Unsafe { *; }
#-keep class com.google.gson.stream.** { *; }
# Application classes that will be serialized/deserialized over Gson
# -keep class mypersonalclass.data.model.** { *; }
It looks exactly the same as what you have, except I don't need the line about the annotations.
You can see I've commented out some classes that I added myself. If you serialize/deserialize your own classes, you need to declare them here in place of the reference to mypersonalclass.data.model. This is really important, as you don't want ProGuard to obfuscate the field or class names that GSON uses for serialization.
I always leave those types of comments in there, so I know how to configure the next library or app.
The previous answer stopped working for me recently probably due to some changes in Android (R8 is used now instead of Proguard). The configuration I use now is as follows (source - GSON examples):
##---------------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 com.google.gson.examples.android.model.** { <fields>; }
# Prevent proguard from stripping interface information from TypeAdapter, TypeAdapterFactory,
# JsonSerializer, JsonDeserializer instances (so they can be used in #JsonAdapter)
-keep class * implements com.google.gson.TypeAdapter
-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 found out that classes whose fields are annotated by #SerializedName do not have to be explicitly listed unless they are inner classes.
In my case, I just used GSON for deserializing JSON to an Object. So it was enough to add the following line to proguard file.
-keep class your.data.object.modals.package.** { <fields>; }
In my case I added the above but still got an error until in my app level gradle I changed compile 'org.immutables:gson:2.4.6' to provided 'org.immutables:gson:2.4.6'. Maybe someone more enlightened can explain why but this solved my problem.
Using -keep is a bad practice and you should never do it .You almost never want to use -keep; if you do need a ProGuard rule, you usually want one of the more specific variants
-keepclassmembers - This protects only the members of the class from shrinking and obfuscation.
-keepnames - This allows shrinking for classes and members, but not obfuscation. That is, any unused code is going to get removed. But the code that is kept will keep its original names.
-keepclassmembernames - Unused classes are removed, the remaining classes are renamed, unused members of those classes are removed, but then the remaining members keep their original names.
For more information please read this
PS - this is what I did for Gson
-keepclassmembernames class rscom.pojo.** { <fields>; }

MalformedParameterizedTypeException when using proguard

I'm using proguard to shrink a shaded jar for use as a command line tool. The shaded jar works fine but I'm getting an exception when running the jar created by proguard. The app uses Guice injection and I added configuration that I found on SO, mostly in this answer.
This is the Exception:
Exception in thread "main" java.lang.reflect.MalformedParameterizedTypeException
at sun.reflect.generics.reflectiveObjects.ParameterizedTypeImpl.validateConstructorArguments(ParameterizedTypeImpl.java:60)
at sun.reflect.generics.reflectiveObjects.ParameterizedTypeImpl.<init>(ParameterizedTypeImpl.java:53)
at sun.reflect.generics.reflectiveObjects.ParameterizedTypeImpl.make(ParameterizedTypeImpl.java:95)
at sun.reflect.generics.factory.CoreReflectionFactory.makeParameterizedType(CoreReflectionFactory.java:105)
at sun.reflect.generics.visitor.Reifier.visitClassTypeSignature(Reifier.java:140)
at sun.reflect.generics.tree.ClassTypeSignature.accept(ClassTypeSignature.java:49)
at sun.reflect.generics.repository.ClassRepository.getSuperclass(ClassRepository.java:84)
at java.lang.Class.getGenericSuperclass(Class.java:696)
at com.google.inject.internal.MoreTypes.getGenericSupertype(MoreTypes.java:273)
at com.google.inject.TypeLiteral.getSupertype(TypeLiteral.java:257)
at com.google.inject.spi.InjectionPoint.hierarchyFor(InjectionPoint.java:755)
at com.google.inject.spi.InjectionPoint.getInjectionPoints(InjectionPoint.java:635)
at com.google.inject.spi.InjectionPoint.forInstanceMethodsAndFields(InjectionPoint.java:356)
at com.google.inject.internal.ConstructorBindingImpl.getInternalDependencies(ConstructorBindingImpl.java:151)
at com.google.inject.internal.InjectorImpl.getInternalDependencies(InjectorImpl.java:585)
at com.google.inject.internal.InjectorImpl.cleanup(InjectorImpl.java:543)
at com.google.inject.internal.InjectorImpl.initializeJitBinding(InjectorImpl.java:529)
at com.google.inject.internal.InjectorImpl.createJustInTimeBinding(InjectorImpl.java:847)
at com.google.inject.internal.InjectorImpl.createJustInTimeBindingRecursive(InjectorImpl.java:772)
at com.google.inject.internal.InjectorImpl.getJustInTimeBinding(InjectorImpl.java:256)
at com.google.inject.internal.InjectorImpl.getBindingOrThrow(InjectorImpl.java:205)
at com.google.inject.internal.InjectorImpl.getInternalFactory(InjectorImpl.java:853)
at com.google.inject.internal.FactoryProxy.notify(FactoryProxy.java:46)
at com.google.inject.internal.ProcessedBindingData.runCreationListeners(ProcessedBindingData.java:50)
at com.google.inject.internal.InternalInjectorCreator.initializeStatically(InternalInjectorCreator.java:133)
at com.google.inject.internal.InternalInjectorCreator.build(InternalInjectorCreator.java:106)
at com.google.inject.Guice.createInjector(Guice.java:95)
at com.google.inject.Guice.createInjector(Guice.java:72)
at com.google.inject.Guice.createInjector(Guice.java:62)
at com.acme.ui.cli.Main.main(Main.java:44)
And this the configuration that's producing it:
-injars acme-cli-0.2.1-SNAPSHOT.jar
-outjars target/acme-cli-0.2.1-SNAPSHOT.jar
-libraryjars /Library/Java/JavaVirtualMachines/jdk1.7.0_25.jdk/Contents/Home/jre/lib/jce.jar
-libraryjars /Library/Java/JavaVirtualMachines/jdk1.7.0_25.jdk/Contents/Home/jre/lib/jsse.jar
-libraryjars /Library/Java/JavaVirtualMachines/jdk1.7.0_25.jdk/Contents/Home/jre/lib/rt.jar
-dontobfuscate
-dontpreverify
-dontoptimize
-printmapping mapping.map
-ignorewarnings
-keepattributes *Annotation*,Signature
# Keep - Applications. Keep all application classes, along with their 'main' methods.
-keep public class com.acme.ui.cli.Main {
public static void main(java.lang.String[]);
}
# Keep Guice-related classes
-keep public class javax.inject.**
-keep class com.google.inject**
-keep class * extends com.google.inject.AbstractModule
# keeps all fields and Constructors annotated with #Inject and #AssistedInject
-keepclasseswithmembers class * {
#com.google.inject.Inject <fields>;
#com.google.inject.Inject <init>(...);
}
-keepclasseswithmembers class * {
#com.google.inject.assistedinject.AssistedInject <fields>;
#com.google.inject.assistedinject.AssistedInject <init>(...);
}
When I add this the problem goes away:
-keep class * {
<init>(...);
}
But it keeps many more classes and doubles the size of the jar. I'm using proguard 4.10 and tried 4.9 too. These are some of the option I've experimented with that seemed most relevant:
-keepattributes *
-keepparameternames
-keep class sun.reflect.generics.reflectiveObjects.ParameterizedTypeImpl {
<init>(...);
}
Since it's seems related to Guice and keeping all constructors solves the problem, I've also experimented with the various ways you can configure the keep options without results. But I must say that I don't understand them fully.
I'm not sure if it's related to the problem, but what looks odd is that the only constructor in the class ParameterizedTypeImpl has a signature like this: private ParameterizedTypeImpl(java.lang.Class<?> aClass, java.lang.reflect.Type[] types, java.lang.reflect.Type type), but the signature in the stacktrace looks like it's accepting ParameterizedTypeImpl itself: ParameterizedTypeImpl.<init>(ParameterizedTypeImpl.java:53).
Now I'm stuck; Any suggestions that could help me further are very appreciated.
This is a known bug that was fixed in Proguard 5.0. See https://sourceforge.net/p/proguard/bugs/518/

Android Javascript Interface Fail

I am using Javascript Interface in my application.
When i run Debug on my device(Galaxy 3) it run perfectly without any problem,but when i make a release apk file the JavaScript is probably not running.
This is the JavaScriptInterface Class:
public class StreamingMediaPlayer{
public class JavaScriptInterface {
Context mContext;
JavaScriptInterface(Context c) {
mContext = c;
}
#JavascriptInterface
public void FinishExtract(String url) {
}
}
}
Now i think it's because the proguard file:
# To enable ProGuard in your project, edit project.properties
# to define the proguard.config property as described in that file.
#
# Add project specific ProGuard rules here.
# By default, the flags in this file are appended to flags specified
# in ${sdk.dir}/tools/proguard/proguard-android.txt
# You can edit the include path and order by changing the ProGuard
# include property in project.properties.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html
# Add any project specific keep options here:
# 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 *;
#}
-dontwarn org.apache.commons.codec.binary.**
-dontwarn com.commonsware.cwac.sacklist.**
-dontwarn com.commonsware.cwac.tlv.**
-dontwarn com.nineoldandroids.**
-dontwarn com.apps.model.**
-keep class com.millennialmedia.android.** {*;}
-keep public class cmn.Proguard$KeepMembers
-keep public class * implements cmn.Proguard$KeepMembers
-keepclassmembers class * implements cmn.Proguard$KeepMembers {
<methods>;
}
-keepattributes *Annotation*
-dontwarn android.webkit.JavascriptInterface
-keep class com.apps.model.** { *; }
-keepattributes *Annotation*
Did i need to add something to the proguard File? Did the problem can be something else?
The problem is that proguard obfuscates the FinishExtract method.
Then the javascript can't find it because it assumes the name is still "FinishExtract"
To fix it you can change your code to:
public class JavaScriptInterface implements cmn.Proguard.KeepMembers {
Your proguard config specifies that classes which implement KeepMembers should stay unobfuscated.

Categories

Resources