Gson parsing is not working when ProGuard rule enabled - android-volley

[![Proguard rules][gson parsing version 2.8.0]][android official volley version 1.0.0]
Gson parsing is not working when ProGuard rules enabled. i have used official version of Volley 1.0.0 and Gson version 2.8.0. So, whenever I enable ProGuard rules, Gson parsing is not working. I have also added required rules in proguard-rules.pro file still it is not working.
Dependency
compile 'com.google.code.gson:gson:2.8.0'
compile 'com.android.volley:volley:1.0.0'
ProGuard rules:
-ignorewarnings
-keep class org.joda.** { *; }
-dontwarn org.joda.convert.FromString
-dontwarn org.joda.convert.ToString
-dontwarn org.joda.convert.**
-dontwarn org.joda.time.**
-keep class org.joda.time.** { *; }
-keep interface org.joda.time.** { *; }
-dontwarn org.mockito.**
-dontwarn sun.reflect.**
-dontwarn android.test.**
-dontwarn java.lang.management.**
-keepattributes Signature
-keep class com.google.gson.examples.android.model.** { *; }
-keep class com.google.gson.**{ *; }
-dontwarn com.fasterxml.jackson.**
-keep class com.fasterxml.jackson.** { *; }
Parsing method
private static void verifyResponse(final String response, final RequestCode requestCode, final IListener listener) throws IOException, ClassNotFoundException {
if (listener != null) {
ResponseStatus responseStatus;
try {
JSONObject jResult = new JSONObject(response);
if (jResult.has("d")) {
String strResult = jResult.getString("d");
jResult = new JSONObject(strResult);
Debug.trace("ResponseStatusA " + jResult.toString());
}
responseStatus = gson.fromJson(new JSONObject(jResult.toString()).toString(), ResponseStatus.class);
Debug.trace("ResponseStatusB " + responseStatus.getStatus());
processSuccess(jResult.toString(), responseStatus, requestCode, listener);
/* if (responseStatus.isFail()) {
processError(responseStatus, listener);
} else {
if (responseStatus.isSuccess()) {
listener.onHideProgressDialog();
processSuccess(jResult.toString(), responseStatus, requestCode, listener);
}
}*/
} catch (JsonSyntaxException | JSONException e) {
e.printStackTrace();
}
}
}

You're missing a rule for ResponseStatus:
-keep class com.yourapp.yourpackage.ResponseStatus { *; }
What's probably happening is that ProGuard is obfuscating the methods and fields of ResponseStatus and when Gson tries to set them their name no longer matches. Remember that you need a -keep class rule for every model class that you use with Gson.

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>; }

Add Below Proguard Rules in proguard-rules.pro file in Android Sutdio.
Gson
-keep class sun.misc.Unsafe { *; }
-keep class com.google.gson.stream.** { *; }
Keep You Model Exclude From Proguard
-keepclassmembers class com.yourpackage.models** { <fields>; }
-keep class com.yourpackage.models{ *; }

Related

java.lang.NoSuchMethodError: No static method asAttributeSet(Lt/g/a/a;)Landroid/util/AttributeSet; in class Landroid/util/Xml;

Complete error
java.lang.NoSuchMethodError: No static method asAttributeSet(Lt/g/a/a;)Landroid/util/AttributeSet; in class Landroid/util/Xml; or its super classes (declaration of 'android.util.Xml' appears in /system/framework/framework.jar!classes2.dex)
I have uploaded appbundle on play store, and whenever I download the app from it in my device, app crashes with logs as below... (logs are collected from all the RedMI devices android os 9, MIUI 11 and 10)
java.lang.NoSuchMethodError: No static method asAttributeSet(Lt/g/a/a;)Landroid/util/AttributeSet; in class Landroid/util/Xml; or its super classes (declaration of 'android.util.Xml' appears in /system/framework/framework.jar!classes2.dex)
at i.b.k.h.g.inflate(Unknown Source:21)
at xxx.yyyyyy.zzzzzz.qqqqqq.cccc.view.HomeActivity.onCreateOptionsMenu(Unknown Source:12)
at android.app.Activity.onCreatePanelMenu(Activity.java:3456)
at android.support.v4.app.i.onCreatePanelMenu(Unknown Source:2)
at i.b.k.h.i.onCreatePanelMenu(Unknown Source:2)
at android.support.v7.app.h$k.onCreatePanelMenu(Unknown Source:8)
at i.b.k.h.i.onCreatePanelMenu(Unknown Source:2)
at android.support.v7.app.l.p(Unknown Source:25)
at android.support.v7.app.l$a.run(Unknown Source:2)
at android.os.Handler.handleCallback(Handler.java:794)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:176)
at android.app.ActivityThread.main(ActivityThread.java:6651)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:547)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:824)
app.gradle
apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'
apply plugin: 'kotlin-kapt'
apply plugin: 'io.fabric'
android {
lintOptions {
checkReleaseBuilds false
abortOnError false
}
compileSdkVersion rootProject.ext.androidCompileSdkVersion
defaultConfig {
applicationId "xxx.yyyyyy.zzzzzz"
minSdkVersion rootProject.ext.androidMinSdkVersion
targetSdkVersion rootProject.ext.androidTargetSdkVersion
versionCode 1
versionName "1.0"
resValue "string", "app_name", "zzzzzz"
vectorDrawables.useSupportLibrary = true
multiDexEnabled true
}
kapt {
generateStubs = true
}
flavorDimensions "default"
productFlavors {
stage {
applicationId "xxx.yyyyyy.zzzzzz.stage"
versionCode 10000
versionName "3.0.55"
dimension "default"
}
dev {
applicationId "xxx.yyyyyy.zzzzzz.dev"
versionCode 10
versionName "3.0.20"
dimension "default"
}
prod {
applicationId "xxx.yyyyyy.zzzzzz"
versionCode 1000
versionName "3.1.12"
dimension "default"
}
}
dynamicFeatures = [":apphub"]
signingConfigs {
release {
storeFile file(getProjectDir().parent + "/Keystore/swipe.keystore")
}
}
buildTypes {
release {
minifyEnabled true
signingConfig signingConfigs.debug
applicationVariants.all { variant ->
renameAPK(variant)
}
}
}
compileOptions {
sourceCompatibility = '1.8'
targetCompatibility = '1.8'
}
dataBinding {
enabled = true
}
dexOptions {
javaMaxHeapSize "4g"
}
packagingOptions {
pickFirst 'lib/armeabi-v7a/libRSSupport.so'
pickFirst 'lib/arm64-v8a/libRSSupport.so'
pickFirst 'lib/x86_64/libRSSupport.so'
pickFirst 'lib/x86/libRSSupport.so'
pickFirst 'lib/mips/libRSSupport.so'
pickFirst 'lib/armeabi-v7a/librsjni.so'
pickFirst 'lib/arm64-v8a/librsjni.so'
pickFirst 'lib/x86_64/librsjni.so'
pickFirst 'lib/x86/librsjni.so'
pickFirst 'lib/mips/librsjni.so'
pickFirst 'lib/x86_64/librsjni_androidx.so'
pickFirst 'lib/armeabi-v7a/librsjni_androidx.so'
pickFirst 'lib/x86/librsjni_androidx.so'
pickFirst 'lib/arm64-v8a/librsjni_androidx.so'
}
}
dependencies {
implementation fileTree(include: ['*.jar'], dir: 'libs')
implementation "com.android.support:support-v4:$supportLibraryVersion"
implementation "com.android.support.constraint:constraint-layout:$contraintLayoutVersion"
// Android Support libs
implementation "com.android.support:appcompat-v7:$supportLibraryVersion"
implementation "com.android.support:design:$supportLibraryVersion"
implementation "com.android.support.constraint:constraint-layout:$contraintLayoutVersion"
implementation "com.android.support:cardview-v7:$supportLibraryVersion"
implementation "com.android.support:recyclerview-v7:$supportLibraryVersion"
// Kotlin libs
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
// Retrofit, GSON and OkHttp
implementation "com.squareup.retrofit2:retrofit:$retrofitLibraryVersion"
implementation "com.google.code.gson:gson:$gsonLibraryVersion"
implementation "com.squareup.retrofit2:converter-gson:$retrofitLibraryVersion"
implementation "com.squareup.retrofit2:adapter-rxjava2:$retrofitLibraryVersion"
implementation "io.reactivex.rxjava2:rxandroid:$rxAndroidVersion"
implementation "com.squareup.okhttp3:okhttp:$okHttpLibraryVersion"
implementation "com.squareup.okhttp3:logging-interceptor:$okHttpLibraryVersion"
// Architecture Libs
implementation "android.arch.lifecycle:extensions:$archVersion"
implementation "android.arch.persistence.room:runtime:$archVersion"
implementation "android.arch.lifecycle:runtime:$archVersion"
implementation "android.arch.persistence.room:rxjava2:$archVersion"
kapt "android.arch.lifecycle:compiler:$archVersion"
kapt "android.arch.persistence.room:compiler:$archVersion"
implementation "android.arch.paging:runtime:$pagingVersion"
implementation "android.arch.work:work-runtime-ktx:$workerVersion"
// Picasso
implementation "com.squareup.picasso:picasso:$picassoLibraryVersion"
//GCM libs
implementation "com.google.android.gms:play-services-location:$playserviceLibraryVersion"
// Google places
implementation "com.google.android.gms:play-services-places:$playserviceLibraryVersion"
//google auth
implementation 'com.google.android.gms:play-services-auth:16.0.1'
// Exo player lib
implementation 'com.google.android.exoplayer:exoplayer:2.9.1'
implementation 'com.pierfrancescosoffritti.androidyoutubeplayer:core:8.0.1'
implementation('com.crashlytics.sdk.android:crashlytics:2.9.5#aar') {
transitive = true
}
// library for generating QR code
implementation 'com.google.zxing:core:3.3.0'
implementation 'com.journeyapps:zxing-android-embedded:3.3.0#aar'
implementation 'com.intuit.sdp:sdp-android:1.0.5'
implementation 'com.intuit.ssp:ssp-android:1.0.5'
implementation 'com.github.bumptech.glide:glide:4.9.0'
implementation('com.github.bumptech.glide:okhttp3-integration:4.9.0') {
exclude group: 'glide-parent'
}
// MixPanel analytics & Play Service GCM
implementation 'com.mixpanel.android:mixpanel-android:5.4.1'
implementation "com.google.android.gms:play-services-gcm:$playserviceLibraryVersion"
implementation "com.google.firebase:firebase-core:$firebaseCoreVersion"
implementation "com.google.firebase:firebase-messaging:$firebaseMessagingVersion"
// Skeleton view lib
implementation 'com.ethanhua:skeleton:1.1.1'
implementation 'io.supercharge:shimmerlayout:2.1.0'
//ProgressDialog
implementation 'com.wang.avi:library:2.1.3'
implementation 'com.facebook.android:facebook-login:5.0.0'
implementation project(':banking')
implementation project(':content')
implementation project(':messaging')
implementation project(':shopping')
implementation project(':base')
implementation project(':travel')
implementation project(':event')
implementation 'com.github.GoodieBag:Pinview:v1.3'
debugImplementation 'com.amitshekhar.android:debug-db:1.0.6'
implementation 'com.appsflyer:af-android-sdk:4.9.0'
implementation 'com.android.installreferrer:installreferrer:1.0'
implementation 'com.makeramen:roundedimageview:2.3.0'
implementation "ru.tinkoff.scrollingpagerindicator:scrollingpagerindicator:1.0.6"
implementation "com.daimajia.swipelayout:library:1.2.0#aar"
implementation 'io.branch.sdk.android:library:3.1.0'
//dynamic feature
implementation 'com.google.android.play:core:1.4.1'
}
repositories {
mavenCentral()
google()
maven { url 'https://maven.fabric.io/public' }
maven { url "https://jitpack.io" }
}
configurations {
compile.exclude group: 'androidx.annotation', module: 'annotation'
}
configurations.all {
resolutionStrategy.force 'com.android.support:support-v4:28.0.0'
}
static def renameAPK(variant) {
variant.outputs.all { output ->
def formattedDate = new Date().format('dd-MM-YYYY')
def projectName = variant.mergedFlavor.resValues.get('app_name').getValue()
def projectVersionName = "_v" + variant.productFlavors.get(0).versionName
def projectBuildCode = "_b" + variant.productFlavors.get(0).versionCode
def buildDate = "_d" + formattedDate
def flavorsName = "_" + variant.productFlavors.get(0).name
def flavorsType = "_" + variant.variantData.variantConfiguration.buildType.name
def fileName = projectName + projectVersionName + projectBuildCode + buildDate + flavorsName + flavorsType + ".apk"
outputFileName = fileName
}
}
apply plugin: 'com.google.gms.google-services'
dynamicModule build.gradle (apphub)
apply plugin: 'com.android.dynamic-feature'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'
apply plugin: 'kotlin-kapt'
androidExtensions {
experimental = true
}
android {
compileSdkVersion rootProject.ext.androidCompileSdkVersion
defaultConfig {
minSdkVersion rootProject.ext.androidMinSdkVersion
targetSdkVersion rootProject.ext.androidTargetSdkVersion
versionCode 1
versionName "1.0"
vectorDrawables.useSupportLibrary = true
}
flavorDimensions "default"
productFlavors {
stage {
applicationId "xxx.yyyyyy.zzzzzz.stage"
versionCode 10000
versionName "2.12"
dimension "default"
}
dev {
applicationId "xxx.yyyyyy.zzzzzz.dev"
versionCode 10
versionName "0.16"
dimension "default"
}
prod {
applicationId "xxx.yyyyyy.zzzzzz.apphub"
versionCode 1000
versionName "3.1.12"
dimension "default"
}
}
dataBinding {
enabled = true
}
kapt {
generateStubs = true
}
compileOptions {
sourceCompatibility 1.8
targetCompatibility 1.8
}
}
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation project(':app')
implementation project(':base')
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
implementation "com.android.support:appcompat-v7:$supportLibraryVersion"
implementation "com.android.support.constraint:constraint-layout:$contraintLayoutVersion"
implementation "com.android.support:design:$supportLibraryVersion"
implementation 'com.intuit.sdp:sdp-android:1.0.5'
implementation 'com.intuit.ssp:ssp-android:1.0.5'
implementation "com.squareup.picasso:picasso:$picassoLibraryVersion"
implementation "com.google.code.gson:gson:$gsonLibraryVersion"
implementation "android.arch.lifecycle:extensions:$archVersion"
implementation "com.android.support:cardview-v7:$supportLibraryVersion"
implementation "com.squareup.retrofit2:retrofit:$retrofitLibraryVersion"
implementation "com.google.code.gson:gson:$gsonLibraryVersion"
implementation "com.squareup.retrofit2:converter-gson:$retrofitLibraryVersion"
implementation "com.squareup.retrofit2:adapter-rxjava2:$retrofitLibraryVersion"
implementation "io.reactivex.rxjava2:rxandroid:$rxAndroidVersion"
implementation "com.squareup.okhttp3:okhttp:$okHttpLibraryVersion"
implementation "com.squareup.okhttp3:logging-interceptor:$okHttpLibraryVersion"
implementation 'com.jakewharton.rxbinding2:rxbinding:2.1.1'
implementation 'com.google.android.exoplayer:exoplayer:2.9.1'
}
dynamic module androidManifest.xml (apphub)
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:dist="http://schemas.android.com/apk/distribution"
package="xxx.yyyyyy.zzzzzz.apphub">
<dist:module
dist:onDemand="false"
dist:instant="false"
dist:title="#string/title_app_hub">
<dist:fusing dist:include="true"/>
</dist:module>
<application>
<activity
android:name="xxx.yyyyyy.zzzzzz.qqqqqqqqq.aaaaaaaaa.AppHubActivity"
android:windowSoftInputMode="stateHidden|adjustPan"
android:screenOrientation="portrait" />
</application>
</manifest>
method to download module runtime
private fun installDynamicModule(intent: Intent) {
val int:Intent = intent
var manager: SplitInstallManager = SplitInstallManagerFactory.create(this#MainActivity)
val request: SplitInstallRequest = SplitInstallRequest.newBuilder().addModule("apphub").build()
if (manager.installedModules.contains("apphub")) {
startActivity(int)
Log.e("main","main: activity start without download")
} else{
manager.startInstall(request)
.addOnSuccessListener {
Toast.makeText(this#MainActivity, "Download Success", Toast.LENGTH_SHORT).show()
Log.e("main","main: addOnSuccessListener")
}
.addOnFailureListener {
Toast.makeText(this#MainActivity, "Download Fail", Toast.LENGTH_SHORT).show()
Log.e("main","main: addOnFailureListener")
}
.addOnCompleteListener {
startActivity(int)
Toast.makeText(this#MainActivity, "Download Complete", Toast.LENGTH_SHORT).show()
Log.e("main","main: addOnCompleteListener")
}
}
proguard of app module
# Add project specific ProGuard rules here.
# By default, the flags in this file are appended to flags specified
# in /Users/mavya.soni/Desktop/Software/AndroidTools/sdk/android-sdk-macosx/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
-keep class sun.misc.Unsafe { *; }
-dontwarn java.nio.file.*
-dontwarn org.codehaus.mojo.animal_sniffer.IgnoreJRERequirement
-dontwarn okio.**
# OkHttp
-keepattributes Signature
-keepattributes *Annotation*
-keep class okhttp3.** { *; }
-keep interface okhttp3.** { *; }
-dontwarn okhttp3.**
# Retrofit 2.X
## https://square.github.io/retrofit/ ##
-dontwarn retrofit2.**
-keep class retrofit2.** { *; }
-keepattributes Signature
-keepattributes Exceptions
-keepclasseswithmembers class * {
#retrofit2.http.* <methods>;
}
## Square Picasso specific rules ##
## https://square.github.io/picasso/ ##
-dontwarn com.squareup.okhttp.**
## Rxjava
-dontwarn sun.misc.**
# rxjava
-keep class rx.schedulers.Schedulers {
public static <methods>;
}
-keep class rx.schedulers.ImmediateScheduler {
public <methods>;
}
-keep class rx.schedulers.TestScheduler {
public <methods>;
}
-keep class rx.schedulers.Schedulers {
public static ** test();
}
-keepclassmembers class rx.internal.util.unsafe.*ArrayQueue*Field* {
long producerIndex;
long consumerIndex;
}
-keepclassmembers class rx.internal.util.unsafe.BaseLinkedQueueProducerNodeRef {
long producerNode;
long consumerNode;
}
-keepclassmembers class rx.internal.util.unsafe.*ArrayQueue*Field* {
long producerIndex;
long consumerIndex;
}
-keepclassmembers class rx.internal.util.unsafe.BaseLinkedQueueProducerNodeRef {
rx.internal.util.atomic.LinkedQueueNode producerNode;
}
-keepclassmembers class rx.internal.util.unsafe.BaseLinkedQueueConsumerNodeRef {
rx.internal.util.atomic.LinkedQueueNode consumerNode;
}
-dontnote rx.internal.util.PlatformDependent
## Android architecture components: Lifecycle
# LifecycleObserver's empty constructor is considered to be unused by proguard
-keepclassmembers class * implements android.arch.lifecycle.LifecycleObserver {
<init>(...);
}
# ViewModel's empty constructor is considered to be unused by proguard
-keepclassmembers class * extends android.arch.lifecycle.ViewModel {
<init>(...);
}
# keep Lifecycle State and Event enums values
-keepclassmembers class android.arch.lifecycle.Lifecycle$State { *; }
-keepclassmembers class android.arch.lifecycle.Lifecycle$Event { *; }
# keep methods annotated with #OnLifecycleEvent even if they seem to be unused
# (Mostly for LiveData.LifecycleBoundObserver.onStateChange(), but who knows)
-keepclassmembers class * {
#android.arch.lifecycle.OnLifecycleEvent *;
}
-keepclassmembers class * implements android.arch.lifecycle.LifecycleObserver {
<init>(...);
}
-keep class * implements android.arch.lifecycle.LifecycleObserver {
<init>(...);
}
-keepclassmembers class android.arch.** { *; }
-keep class android.arch.** { *; }
-dontwarn android.arch.**
-keepclasseswithmembernames class * {
native <methods>;
}
-ignorewarnings
-keep class android.support.v8.renderscript.** { *; }
-keep class com.crashlytics.** { *; }
-dontwarn com.crashlytics.**
### OKIO
# java.nio.file.* usage which cannot be used at runtime. Animal sniffer annotation.
-dontwarn okio.Okio
# JDK 7-only method which is #hide on Android. Animal sniffer annotation.
-dontwarn okio.DeflaterSink
# com.google.zxing lib
# test thoroughly if you go this route.
-optimizations !code/simplification/cast,!field/*,!class/merging/*,!class/unboxing/enum,!code/allocation/variable,!method/marking/private
-optimizationpasses 5
-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
# ADDED
-dontshrink
#-dontobfuscate
-keepattributes *Annotation*
-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>;
}
-keep class android.databinding.** { *; }
-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();
}
-keepattributes *Annotation*
#-keepattributes javax.xml.bind.annotation.*
#-keepattributes javax.annotation.processing.*
-keepclassmembers class * extends java.lang.Enum { *; }
-keepclasseswithmembernames class android.**
-keepclasseswithmembernames interface android.**
#-dontobfuscate
-libraryjars <java.home>/lib/rt.jar
-libraryjars <java.home>/lib/jce.jar
-dontwarn
# 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.**
#-printmapping prod/release/mapping/mapping.txt
-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.** { *; }
-keep class com.wang.avi.** { *; }
-keep class com.wang.avi.indicators.** { *; }
# 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
##---------------End: proguard configuration for Gson ----------
-keep class * implements com.coremedia.iso.boxes.Box {* ; }
-dontwarn com.coremedia.iso.boxes.*
-dontwarn com.googlecode.mp4parser.authoring.tracks.mjpeg.**
-dontwarn com.googlecode.mp4parser.authoring.tracks.ttml.**
# Preserve annotations, line numbers, and source file names
-keepattributes *Annotation*,SourceFile,LineNumberTable
-keep class com.appsflyer.** { *; }
# Proguard rule for XMLResourceParser
-keep class org.xmlpull.v1.** { *; }
-dontwarn org.xmlpull.v1.**
-dontwarn com.android.installreferrer.api.**
this is only happening after downloading the app from the play store. It works fine with debug but not working with the signed app bundle.
You must add this to your proguard-rules.pro file
-dontwarn org.xmlpull.v1.XmlPullParser
-dontwarn org.xmlpull.v1.XmlSerializer
-keep class org.xmlpull.v1.* {*;}

//NonCompliant comment usage - SonarQube Custom Rule

I am trying to write a few SONARQUBE custom rules for my project.
After reading up the below document -
https://docs.sonarqube.org/display/PLUG/Writing+Custom+Java+Rules+101
and
https://github.com/SonarSource/sonar-custom-rules-examples,
I created a custom rule like these classes below -
The Rule file:
#Rule(key = "MyAssertionRule")
public class FirstSonarCustomRule extends BaseTreeVisitor implements JavaFileScanner {
private static final String DEFAULT_VALUE = "Inject";
private JavaFileScannerContext context;
/**
* Name of the annotation to avoid. Value can be set by users in Quality
* profiles. The key
*/
#RuleProperty(defaultValue = DEFAULT_VALUE, description = "Name of the annotation to avoid, without the prefix #, for instance 'Override'")
protected String name;
#Override
public void scanFile(JavaFileScannerContext context) {
this.context = context;
System.out.println(PrinterVisitor.print(context.getTree()));
scan(context.getTree());
}
#Override
public void visitMethod(MethodTree tree) {
List<StatementTree> statements = tree.block().body();
for (StatementTree statement : statements) {
System.out.println("KIND IS " + statement.kind());
if (statement.is(Kind.EXPRESSION_STATEMENT)) {
if (statement.firstToken().text().equals("Assert")) {
System.out.println("ERROR");
}
}
}
}
}
The Test class:
public class FirstSonarCustomRuleTest {
#Test
public void verify() {
FirstSonarCustomRule f = new FirstSonarCustomRule();
f.name = "ASSERTION";
JavaCheckVerifier.verify("src/test/files/FirstSonarCustom.java", f);
}
}
And finally - the Test file:
class FirstSonarCustom {
int aField;
public void methodToUseTestNgAssertions() {
Assert.assertTrue(true);
}
}
The above Test file would later be my Project's source code.
As per the SONAR documentation - the // Noncompliant is a mandatory comment in my Test file. Thus my first question is should I add this comment everywhere in my Source code too?
If yes - is there any way I can avoid adding this comment, because I do not want to add that code refactoring exercise all over.
Can someone suggest me what I need to do here?
I am using SONARQUBE 6.3.
This comment is only used by the test framework (JavaCheckVerifier class) to test the implementation of your rule. It is not mandatory in any way and for sure you don't need it in your real code.

Why is PropertyState Necessary

Suppose I'm developing a Gradle plugin and the inputs that some of the tasks the plugin configures depend on how it is configured via an extension. For example:
class MyTask extends DefaultTask {
#InputFile
File toTrack
#TaskAction
def run() {
println("The file now contains ${toTrack.text}")
}
}
class MyConfig {
File toTrack = new File('bad-default.txt')
}
class MyPlugin implements Plugin<Project> {
#Override
def apply(Project project) {
project.with {
extensions.create('config', MyConfig)
task('printChanges', type: MyTask) {
toTrack = config.toTrack
}
}
}
}
Unfortunately, this doesn't work correctly. The problem is that if I have a build.gradle like:
apply plugin: my-plugin
config {
toTrack = file('file-to-track.txt')
}
where I've specified a file to track, Gradle will evaluate the #InputFile on my task before the config block is run so it'll decide if the task is up to date or not by looking at bad-default.txt rather than file-to-track.txt.
The recommended fix to this seems to be to use PropertyState like so:
class MyTask extends DefaultTask {
PropertyState<File> toTrack = project.property(File)
#InputFile
File getToTrack { return toTrack.get() }
#TaskAction
def run() {
println("The file now contains ${toTrack.get().text}")
}
}
class MyConfig {
private PropertyState<File> toTrack
MyConfig(Project project) {
toTrack = = project.property(File)
toTrack.set('bad-default.txt')
}
void setToTrack(File fileToTrack) { toTrack.set(fileToTrack) }
}
class MyPlugin implements Plugin<Project> {
#Override
def apply(Project project) {
project.with {
extensions.create('config', MyConfig)
task('printChanges', type: MyTask) {
toTrack = config.toTrack
}
}
}
}
That works but it seems very verbose and the PropertyState stuff seems entirely unnecessary. It seems like the real fix was simply to change the #InputFile annotation to be on a getter instead of having it be on the property. In other words, I believe the following has the same effect and is less code and easier to understand:
class MyTask extends DefaultTask {
File toTrack
// This is the only change: put the annotation on a getter
#InputFile
File getToTrack() { return toTrack }
#TaskAction
def run() {
println("The file now contains ${toTrack.text}")
}
}
class MyConfig {
File toTrack = new File('bad-default.txt')
}
class MyPlugin implements Plugin<Project> {
#Override
def apply(Project project) {
project.with {
extensions.create('config', MyConfig)
task('printChanges', type: MyTask) {
toTrack = config.toTrack
}
}
}
}
With some experiments this does seem to have the desired effect. What am I missing? Is there ever a time when PropertyState is necessary?
The problem is not the time #InputFile is evaluated. #InputFile is evaluated just before the task is executed, so after the configuration phase has finished and during gradles execution phase. The problem PropertyState is solving is the wiring between an extension and a task.
let's look again on your apply method:
def apply(Project project) {
project.with {
extensions.create('config', MyConfig)
task('printChanges', type: MyTask) {
toTrack = config.toTrack
}
}
}
here you:
1) Create your custom extension with the default value provided in the MyConfig class.
2) Link the value currently set in MyConfig to the MyTask toTrack property.
Now looking at the plugin usage:
apply plugin: my-plugin
config {
toTrack = file('file-to-track.txt')
}
here you:
1) Apply the plugin (and basically executing the apply method of your plugin).
2) Reconfigure the MyConfig#toTrack extension property.
But what isn't happening here, is updating the value in the printChanges task. That's what PropertyState is solving. It has nothing todo with Task inputs and outputs evaluation.

How to only register Transform in debug buildtype

I wrote a custom gradle plugin for android app, and I register a transform, but i just want to register it when current buildtype is debug. How can i achieve it.
public class CustomPlugin implements Plugin<Project> {
void apply(Project project) {
project.android.registerTransform(new CustomTranform());
}
}
You can get variant name from the context in which the transform is run: javadoc
Which means you can write your transform this way:
class CustomTranform extends Transform {
#Override
public void transform(TransformInvocation invocation) {
String variantName = invocation.getContext().getVariantName();
if (variantName.toLowerCase().endsWith("debug")) {
// actual transform
} else {
// no-op transform
}
}
...
}

CallToDeprecatedMethod rule doesn't work

Since this rule does not work for me I've created easy test "project" structure:
/myTestProject
/src
/a
/A.java
/b
/B.java
And content of .java files:
A.java
package a;
public class A {
public A() {
}
public void someOther() {
halo();
}
/**
* #deprecated
*/
#Deprecated
public void halo() {
int i = 0;
}
}
B.java
package b;
import a.A;
public class B {
public B() {
}
public void halo() {
A a = new A();
a.halo();
}
}
I've enabled Avoid use of deprecated methods in my default quality profile. (Key CallToDeprecatedMethod in squid)
I ran SonarRunner however I don't have any issues in this code.
What have I forget?
EDIT:
My enviroment SonarQube 4.1 and Sonar Runner 2.3
I found answer in the following topic: http://sonarqube.15.x6.nabble.com/sonar-dev-sonar-squid-needs-class-file-td5019909.html#a5019937
As title of this topic says: "sonar squid needs class file"
In this topic we can read that files *.class from our project are required.
I haven't build my project. So there weren't any *.class files.
It's not clearly stated in rules description or other places that *.class files are required.

Resources