Closed oleandre closed 5 years ago
Java or Android? Does R8 work?
Android. Haven't tried R8, should I?
Please do. We might have accidentally made use of an R8-only feature.
From a quick test it seems like proguard doesn't like more than 2 parameters. Could be a parsing bug.
It's a parsing bug that will be fixed in proguard 6.1.0-beta2 https://sourceforge.net/p/proguard/bugs/731/
Is it safe to omit these rules, or do we need to wait for the fix? Maybe some kind of workaround?
I’m wondering if it’s safe to upgrade to 1.7.0 from 1.5.0, use the old rules and release app in production?
It depends on how you use Moshi.
1) If you don't use the Kotlin moshi-kotlin-codegen
artifact at all, it's save to just include this part of the file
https://github.com/square/moshi/blob/master/moshi/src/main/resources/META-INF/proguard/moshi.pro#L1-L14
2) If you do use moshi-kotlin-codegen
it depends on whether you have nested classes that are annotated with @JsonClass
. If you have no nesting or only one level of nesting you can use this part of the file
https://github.com/square/moshi/blob/master/moshi/src/main/resources/META-INF/proguard/moshi.pro#L1-L29
3) If you have deeper nesting you can workaround by using this:
# JSR 305 annotations are for embedding nullability information.
-dontwarn javax.annotation.**
-keepclasseswithmembers class * {
@com.squareup.moshi.* <methods>;
}
-keep @com.squareup.moshi.JsonQualifier interface *
# Enum field names are used by the integrated EnumJsonAdapter.
# Annotate enums with @JsonClass(generateAdapter = false) to use them with Moshi.
-keepclassmembers @com.squareup.moshi.JsonClass class * extends java.lang.Enum {
<fields>;
}
# The name of @JsonClass types is used to look up the generated adapter.
-keepnames @com.squareup.moshi.JsonClass class *
# Retain generated JsonAdapters if annotated type is retained.
-keep class **JsonAdapter {
<init>(...);
<fields>;
}
(this replaces the more specific keep rules with one that keeps all classes with a name that ends with JsonAdapter
)
Hi,
Do you plan to fix rules in the lib's moshi.pro file for ProGuard users? I currently can't use R8 and as the moshi.pro is automatically parsed, I have to disable minifying for my project to build.
Best regards
Any idea how we’d fix it for ProGuard users?
I guess what @gabrielittner provided should be fine: https://github.com/square/moshi/issues/738#issuecomment-437281870
We're using moshi-kotlin-codegen 1.8.0 without any issues since it's been released (19 days ago) but have incurred into this build error yesterday after upgrading Android Gradle plugin from 3.2.1 to 3.3.0-rc01.
No proguard config was changed in the process.
Is this expected behavior?
Same here with 3.3.0-rc01. How can this be fixed?
Could it be related to this
You can force Gradle to use a newer version of ProGuard:
buildscript {
configurations.all {
resolutionStrategy {
force 'net.sf.proguard:proguard-gradle:6.1.0beta1'
}
}
}
However version 6.1.0beta2
that should contain a fix unfortunately hasn't been released yet.
Just found this flag in the AGP source code:
android.proguard.enableRulesExtraction=false
Works for 3.3.0-rc02, but you'll need to add the rules manually without the part which confuses ProGuard. You don't need this if you've enabled R8 or use 3.4.0 where it's enabled by default.
Proguard 6.1.0beta2 is out. Here is a summary of the workarounds:
Copy the proguard rules to your project like described in this comment.
Set android.proguard.enableRulesExtraction=false
and then copy the proguard rules to your project like described in this comment.
OR
Upgrade proguard to 6.1.0beta2:
buildscript {
configurations.all {
resolutionStrategy {
force 'net.sf.proguard:proguard-gradle:6.1.0beta2'
}
}
}
OR
Enable R8 by setting android.enableR8=true
.
Should work by default. If you disabled R8 follow the instructions for AGP 3.3.
Great! Thanks a lot @gabrielittner!
Moshi: 1.8.0 Android Gradle Plugin: 3.3.0
I enabled R8 via android.enableR8=true
but still receive this error :(
Update:
I disabled rules extraction via android.proguard.enableRulesExtraction=false
and copied the Moshi rules into my own ProGuard file. Now I receive the same error regarding <1>_<2>_<3>JsonAdapter
in my own file. I'm not sure why ProGuard still tries to parse these files although R8 is enabled?!
Update 2:
Disabling R8 again and forcing ProGuard 6.1.0beta2 now gives me the following error:
> Failed to notify project evaluation listener.
> proguard.ConfigurationParser.parseClassSpecificationArguments()Lproguard/ClassSpecification;
I seem to be stuck :(
Update 3:
Explicitly specifying useProguard false
wherever minifyEnabled true
is set did also not help.
@svenjacobs Do you have a sample project? Both R8 and ProGuard 6.1.0beta2 work for me.
In regards to your first update. You shouldn't copy all of the rules, only parts of it like described here https://github.com/square/moshi/issues/738#issuecomment-437281870
@gabrielittner I don't have a sample project as the project where the error occurs is quite complex and consists of several modules. I would have to create a sample project.
@gabrielittner I found the issue. The project consists of multiple feature modules. Each feature contained the ProGuard configuration per build type. Although the configuration was identical, once I removed the configuration from the feature modules and only kept it for the app
module everything works.
As a heads up, the Fabric gradle plugin doesn't work with latest beta of ProGuard. It gives this error during configuration. Fabric triggers the issue, but I don't see Fabric in the stacktrace, so it maybe a problem in AGP.
Caused by: java.lang.NoSuchMethodError: proguard.ConfigurationParser.parseClassSpecificationArguments()Lproguard/ClassSpecification;
at com.android.build.gradle.internal.transforms.BaseProguardAction.keep(BaseProguardAction.java:79)
at com.android.build.gradle.internal.TaskManager.applyProguardDefaultsForTest(TaskManager.java:3433)
at com.android.build.gradle.internal.TaskManager.applyProguardRules(TaskManager.java:3366)
at com.android.build.gradle.internal.TaskManager.createProguardTransform(TaskManager.java:3341)
at com.android.build.gradle.internal.TaskManager.doCreateJavaCodeShrinkerTransform(TaskManager.java:3279)
at com.android.build.gradle.internal.TaskManager.maybeCreateJavaCodeShrinkerTransform(TaskManager.java:3244)
at com.android.build.gradle.internal.TaskManager.createPostCompilationTasks(TaskManager.java:2181)
at com.android.build.gradle.internal.TaskManager.createAndroidTestVariantTasks(TaskManager.java:1808)
at com.android.build.gradle.internal.VariantManager.createTasksForVariantData(VariantManager.java:485)
at com.android.build.gradle.internal.VariantManager.createAndroidTasks(VariantManager.java:365)
at com.android.build.gradle.BasePlugin.createAndroidTasks(BasePlugin.java:767)
at com.android.builder.profile.ThreadRecorder.record(ThreadRecorder.java:81)
at com.android.build.gradle.BasePlugin.lambda$createTasks$4(BasePlugin.java:651)
at com.android.build.gradle.internal.crash.CrashReporting$afterEvaluate$1.execute(crash_reporting.kt:37)
at com.android.build.gradle.internal.crash.CrashReporting$afterEvaluate$1.execute(crash_reporting.kt)
at org.gradle.configuration.internal.DefaultListenerBuildOperationDecorator$BuildOperationEmittingAction$1$1.run(DefaultListenerBuildOperationDecorator.java:150)
at org.gradle.configuration.internal.DefaultUserCodeApplicationContext.reapply(DefaultUserCodeApplicationContext.java:58)
at org.gradle.configuration.internal.DefaultListenerBuildOperationDecorator$BuildOperationEmittingAction$1.run(DefaultListenerBuildOperationDecorator.java:147)
This doesn't appear to be specific to Fabric. I get the same error in a non-Fabric app when simply running ./gradlew clean
with AGP 3.3.0 and Proguard 6.1.0beta2. Reverting to the default version of Proguard fixes this error.
Caused by: java.lang.NoSuchMethodError: proguard.ConfigurationParser.parseClassSpecificationArguments()Lproguard/ClassSpecification;
at com.android.build.gradle.internal.transforms.BaseProguardAction.keep(BaseProguardAction.java:79)
at com.android.build.gradle.internal.TaskManager.applyProguardDefaultsForTest(TaskManager.java:3433)
at com.android.build.gradle.internal.TaskManager.applyProguardRules(TaskManager.java:3366)
at com.android.build.gradle.internal.TaskManager.createProguardTransform(TaskManager.java:3341)
at com.android.build.gradle.internal.TaskManager.doCreateJavaCodeShrinkerTransform(TaskManager.java:3279)
at com.android.build.gradle.internal.TaskManager.maybeCreateJavaCodeShrinkerTransform(TaskManager.java:3244)
at com.android.build.gradle.internal.TaskManager.createPostCompilationTasks(TaskManager.java:2181)
at com.android.build.gradle.internal.TaskManager.createAndroidTestVariantTasks(TaskManager.java:1808)
at com.android.build.gradle.internal.VariantManager.createTasksForVariantData(VariantManager.java:485)
at com.android.build.gradle.internal.VariantManager.createAndroidTasks(VariantManager.java:365)
at com.android.build.gradle.BasePlugin.createAndroidTasks(BasePlugin.java:767)
at com.android.builder.profile.ThreadRecorder.record(ThreadRecorder.java:81)
at com.android.build.gradle.BasePlugin.lambda$createTasks$4(BasePlugin.java:651)
at com.android.build.gradle.internal.crash.CrashReporting$afterEvaluate$1.execute(crash_reporting.kt:37)
at com.android.build.gradle.internal.crash.CrashReporting$afterEvaluate$1.execute(crash_reporting.kt)
at org.gradle.configuration.internal.DefaultListenerBuildOperationDecorator$BuildOperationEmittingAction$1$1.run(DefaultListenerBuildOperationDecorator.java:157)
at org.gradle.configuration.internal.DefaultUserCodeApplicationContext.reapply(DefaultUserCodeApplicationContext.java:58)
at org.gradle.configuration.internal.DefaultListenerBuildOperationDecorator$BuildOperationEmittingAction$1.run(DefaultListenerBuildOperationDecorator.java:154)
at org.gradle.internal.operations.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:301)
at org.gradle.internal.operations.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:293)
at org.gradle.internal.operations.DefaultBuildOperationExecutor.execute(DefaultBuildOperationExecutor.java:175)
at org.gradle.internal.operations.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:91)
at org.gradle.configuration.internal.DefaultListenerBuildOperationDecorator$BuildOperationEmittingAction.execute(DefaultListenerBuildOperationDecorator.java:151)
at org.gradle.internal.event.BroadcastDispatch$ActionInvocationHandler.dispatch(BroadcastDispatch.java:91)
at org.gradle.internal.event.BroadcastDispatch$ActionInvocationHandler.dispatch(BroadcastDispatch.java:80)
at org.gradle.internal.event.AbstractBroadcastDispatch.dispatch(AbstractBroadcastDispatch.java:42)
at org.gradle.internal.event.BroadcastDispatch$SingletonDispatch.dispatch(BroadcastDispatch.java:230)
at org.gradle.internal.event.BroadcastDispatch$SingletonDispatch.dispatch(BroadcastDispatch.java:149)
at org.gradle.internal.event.AbstractBroadcastDispatch.dispatch(AbstractBroadcastDispatch.java:58)
... 110 more
Try this rule as a workaround:
-keep public class * extends com.squareup.moshi.JsonAdapter {
<init>(...);
<fields>;
}
And remove all the other rules that include <1>_<2>
and so one (there's like 6 of them).
Working for me without any other changes. Make sure the included rules with the moshi dependency are not in use. I use moshi 1.6.0, so they're not there AFAIK, but you get them if you use 1.8.0.
PS: This is for codegen only! PS2: Copy-pasta rules here: https://gist.github.com/pawelkw/c5bc377ea4fc6cdbd93bc770c0895879
I had the exact same issue with AGP 3.3.0
, Proguard 6.1.0beta2
and moshi 1.8.0
in my custom libraries.
My workaround was to ignore proguard rules being extracted by adding the following to gradle.properties
file :
android.proguard.enableRulesExtraction=false
⚠️ this option setting is experimental
i had this issue when i updated :
I just rollback this and everything is working correctly.
@gabrielittner I found the issue. The project consists of multiple feature modules. Each feature contained the ProGuard configuration per build type. Although the configuration was identical, once I removed the configuration from the feature modules and only kept it for the
app
module everything works.
This was our case too. Only the main :app
module should define proguardFiles()
. If you want specific proguard rules for your feature modules, you can define additional rules using consumerProguardFiles()
:
buildTypes {
release {
consumerProguardFiles("proguard-rules.pro")
}
}
Nice
I faced the same problem when updating android studio 3.4.1
Closing this out now as R8 is now the default in the android gradle plugin and Proguard 6.1.0 stable (and 6.1.1!) is released with support for the modern rules. Please use one of these versions going forward
How would we specify to use Proguard 6.1.0+ ? I am using on moshi version 1.8.0
and Android Plugin 3.3.2
Try this rule as a workaround:
-keep public class * extends com.squareup.moshi.JsonAdapter { <init>(...); <fields>; }
And remove all the other rules that include
<1>_<2>
and so one (there's like 6 of them). Working for me without any other changes. Make sure the included rules with the moshi dependency are not in use. I use moshi 1.6.0, so they're not there AFAIK, but you get them if you use 1.8.0.PS: This is for codegen only! PS2: Copy-pasta rules here: https://gist.github.com/pawelkw/c5bc377ea4fc6cdbd93bc770c0895879
how to Make sure the included rules with the moshi dependency are NOT IN USE?
Android Studio 3.5.2 Build #AI-191.8026.42.35.5977832, built on October 30, 2019 JRE: 1.8.0_202-release-1483-b49-5587405 x86_64 JVM: OpenJDK 64-Bit Server VM by JetBrains s.r.o macOS 10.15.1 Kotlin 1.3.60
- What went wrong: Execution failed for task ':app:transformClassesAndResourcesWithProguardForAlpha'. java.io.IOException: proguard.ParseException: Use of generics not allowed for java type at '<1><2><3>JsonAdapter' in line 43 of file '/Users/drjacky/.gradle/caches/transforms-2/files-2.1/4d48b9430371242423f570ca1beef7fc/META-INF/proguard/moshi.pro'
Proguard:
-printconfiguration "build/outputs/mapping/configuration.txt"
-keepattributes Signature
-keepattributes Exceptions
-keepattributes *Annotation*
-keepattributes SourceFile,LineNumberTable
-dontwarn okhttp3.**
-dontwarn retrofit2.Platform
-dontwarn retrofit2.Platform$Java8
-dontwarn okio.**
-dontwarn javax.annotation.**
-dontwarn org.jetbrains.annotations.**
-dontwarn com.google.errorprone.annotations.*
-dontwarn java.lang.invoke.*
-dontwarn org.codehaus.mojo.animal_sniffer.*
-keep class retrofit2.** { *; }
-keep class okio.** { *; }
-keep class okhttp3.** { *; }
-keep class io.reactivex.** { *; }
-keep class org.reactivestreams.** { *; }
-keep class kotlin.Metadata { *; }
-keep @org.parceler.Parcel class * { *; }
-keep class **$$Parcelable { *; }
-keep interface org.parceler.Parcel
-keep public class * extends java.lang.Exception
-keep @com.squareup.moshi.JsonQualifier interface *
-keep interface kotlin.reflect.jvm.internal.impl.builtins.BuiltInsLoader
-keep class kotlin.reflect.jvm.internal.impl.builtins.BuiltInsLoaderImpl
-keep class kotlin.reflect.jvm.internal.impl.serialization.deserialization.builtins.BuiltInsLoaderImpl
-keep public class * implements com.bumptech.glide.module.GlideModule
-keep public class * extends com.bumptech.glide.module.AppGlideModule
-keep public enum com.bumptech.glide.load.ImageHeaderParser$** {
**[] $VALUES;
public *;
}
-keepclasseswithmembers class * {
@retrofit2.http.* <methods>;
}
-keepclasseswithmembers class * {
@com.squareup.moshi.* <methods>;
}
-keepclassmembers class kotlin.Metadata {
public <methods>;
}
-keepclassmembers class * {
@com.squareup.moshi.FromJson <methods>;
@com.squareup.moshi.ToJson <methods>;
}
# Enum field names are used by the integrated EnumJsonAdapter.
# Annotate enums with @JsonClass(generateAdapter = false) to use them with Moshi.
-keepclassmembers @com.squareup.moshi.JsonClass class * extends java.lang.Enum {
<fields>;
}
-keepclassmembers class kotlin.Metadata {
public <methods>;
}
# The name of @JsonClass types is used to look up the generated adapter.
-keepnames @com.squareup.moshi.JsonClass class *
# Retain generated JsonAdapters if annotated type is retained.
#Uncomment when this bug gets solved: https://youtrack.jetbrains.com/issue/KT-29668
#-if @com.squareup.moshi.JsonClass class *
#-keep class <1>JsonAdapter {
# <init>(...);
# <fields>;
#}
#-if @com.squareup.moshi.JsonClass class **$*
#-keep class <1>_<2>JsonAdapter {
# <init>(...);
# <fields>;
#}
#-if @com.squareup.moshi.JsonClass class **$*$*
#-keep class <1>_<2>_<3>JsonAdapter {
# <init>(...);
# <fields>;
#}
#-if @com.squareup.moshi.JsonClass class **$*$*$*
#-keep class <1>_<2>_<3>_<4>JsonAdapter {
# <init>(...);
# <fields>;
#}
#-if @com.squareup.moshi.JsonClass class **$*$*$*$*
#-keep class <1>_<2>_<3>_<4>_<5>JsonAdapter {
# <init>(...);
# <fields>;
#}
#-if @com.squareup.moshi.JsonClass class **$*$*$*$*$*
#-keep class <1>_<2>_<3>_<4>_<5>_<6>JsonAdapter {
# <init>(...);
# <fields>;
#}
# Moshi - Keep entity names
-keepnames @kotlin.Metadata class com.safeboda.data.entity.**
-keep class com.safeboda.data.entity.** { *; }
-keepclassmembers class com.safeboda.data.entity.** { *; }
-keepnames @kotlin.Metadata class com.safeboda.domain.entity.**
-keep class com.safeboda.domain.entity.** { *; }
-keepclassmembers class com.safeboda.domain.entity.** { *; }
@drjacky see my comment in #1042
@ZacSweers Please take a look at https://github.com/square/moshi/issues/1042#issuecomment-558718625
how to fix this error in Gradle 7.4 up to Gradle Version 7.5.1 please help i try everything
Expecting type and name instead of just 'setExtensionCallback' before '(' in line 380 of file '/Users/AndroidStudioProjects/ProjeckfileName/app/build/intermediates/proguard/configs/release/consumer-rules.pro'
After updating to Moshi 1.7.0 and updating the Proguard-rules I've encountered a Gradle build exception:
Exception while processing task java.io.IOException: proguard.ParseException: Use of generics not allowed for java type at '<1><2><3>JsonAdapter' in line 31 of file '/Library/TeamCity/buildAgent/work/3ce9226b513c2493/dummy/proguard/proguard-moshi.pro'
I'm now using my old proguard rules, and the build works fine, but I would like to know how to use the new Proguard rules. Here's my current rules which seems to work fine:
-dontwarn okio. -dontwarn javax.annotation. -keepclassmembers class { @com.squareup.moshi.FromJson;
@com.squareup.moshi.ToJson ;
}
-keep @com.squareup.moshi.JsonQualifier interface
-keepclassmembers class kotlin.Metadata {
public ;
}
-dontwarn org.jetbrains.annotations.*
-keep class kotlin.Metadata { ; }
-dontwarn kotlin.reflect.jvm.internal. -keep class kotlin.reflect.jvm.internal. { *; }