I am facing an issue while trying to apply ProGuard on a private library release - written in Kotlin. Without ProGuard, the AAR file generated works perfectly out of the box but after applying ProGuard, I have the following error:
java.lang.NoClassDefFoundError: Failed resolution of: Lcom/package/name/CustomInterface$DefaultImpls;
The CustomClass that I need implements the CustomInterface but when I try to call any method of the CustomClass, I get this error.
Already tried setting the kotlinOptions.JvmTarget=1.8 but doesn't work.
Related
I'm getting the below error:
Failed to find a code-generated model provider.
AWS amplify code which throwing this error:
Amplify.addPlugin(new AWSApiPlugin());
Amplify.addPlugin(new AWSDataStorePlugin());
Amplify.configure(context);
I am following the below tutorials:
https://docs.amplify.aws/start/getting-started/generate-model/q/integration/android
https://docs.amplify.aws/cli/graphql-transformer/overview
I have tried generating models and models get generated successfully but still while running the app I am getting above exception.
When you generate models, you should expect to find various code-generated files in your application project. One of them will be app/src/main/java/com/amplifyframework/datastore/generated/model/AmplifyModelProvider.java.
When you build your app, Android Studio will compile that java file into a class file, and include it into your binary.
At runtime, on the phone, the AWSDataStorePlugin() constructor will attempt to find that same AmplifyModelProvider by means of reflection.
I would verify that:
You do actually have the code-generated AmplifyModelProvider;
It is being built successfully;
It is not being stripped out by ProGuard/R8 minification.
If you're still not able to get it working, just use the one-argument version of the AWSDataStorePlugin(...) constructor, instead. That version allows you to explicitly specify the model provider, and does not use runtime reflection.
Amplify.addPlugin(AWSDataStorePlugin(AmplifyModelProvider.getInstance()))
Your datasource needs to be updated:
Try running modelGen, then amplifyPush tasks:
Category
Resource name
Operation
Provider plugin
Api
amplifyDatasource
Update
awscloudformation
I'm using a no-longer maintained Umano's AndroidSlidingUpPanel library in one of my applications:
dependencies {
// .. redacted
implementation 'com.sothree.slidinguppanel:library:3.4.0'
}
Everything worked fine till now. Today I've tried to change the compileSdkVersion from 27 to 28, and the release build started to fail with a Proguard error (minifyEnabled set to true):
$ ./gradlew clean assembleRelease
> Task :app:transformClassesAndResourcesWithProguardForRelease FAILED
ProGuard, version 6.0.3
Reading input...
// many lines with 'Reading program jar...', redacted
Initializing...
Warning: com.sothree.slidinguppanel.SlidingUpPanelLayout: can't find referenced method 'int save(int)' in library class android.graphics.Canvas
// redacted
Warning: there were 1 unresolved references to library class members.
You probably need to update the library versions.
(http://proguard.sourceforge.net/manual/troubleshooting.html#unresolvedlibraryclassmember)
FAILURE: Build failed with an exception.
* What went wrong:
Execution failed for task ':app:transformClassesAndResourcesWithProguardForRelease'.
> java.io.IOException: Please correct the above warnings first.
BUILD FAILED in 2s
I'm using AGP v3.5.0, with android.enableR8=false configuration to favor Proguard over R8.
One of the comments in this issue suggests to ignore the warning using -dontwarn com.sothree.**, which indeed causes the build to pass.
Why this warning started to appear in the first place, and are there any possible ramifications for ignoring it?
Let's analyze the warning message:
Warning: com.sothree.slidinguppanel.SlidingUpPanelLayout: can't find
referenced method 'int save(int)' in library class
android.graphics.Canvas
Library's SlidingUpPanelLayout.java source file indeed includes a android.graphics.Canvas#save(int) method invocation:
final int save = canvas.save(Canvas.CLIP_SAVE_FLAG);
This method is deprecated since API 26, and was marked as #removed in API 28.
The #removed annotation (along with #hide annotation) is being used by doclava tool (AOSP tool which generates public framework API stub, a.k.a. android.jar) to mark public class methods as hidden.
To summarize: the android.graphics.Canvas#save(int) method was removed from the public API, but it is still part of the runtime/framework (see also this). During minification stage Proguard analyzes the bytecode and obviously fails to find the not-anymore-public-api android.graphics.Canvas#save(int) method and displays the above warning.
This method is still present in runtime, therefore Proguard warning can be ignored given two caveats:
Since this method is not part of public API anymore, a particular vendor might alter the framework classes (i.e., by renaming/removing this method) in a way which will cause runtime errors.
This method might be removed in future AOSP version, and you probably won't notice that till this method will be called on affected device.
The warning ignore rule can be narrowed to:
-dontwarn com.sothree.slidinguppanel.SlidingUpPanelLayout
In a long run, I'd suggest to consider patching this library by yourself (by changing the functionality to use the parameterless android.graphics.Canvas#save() method), or if that's not possible - migrate to another solution.
The ContentResolver class has a hidden method called getSyncStatus(...).
To make it public visible I try to add a wrapper method in ContentResolverCompat from support v4 lib.
This works so far in Eclipse but when I call make it fails with the following errors:
ERROR: /development/android/frameworks/support/v4/java/android/support/v4/content/SyncStatusInfo.java:91: android.content.SyncStatusInfo cannot be resolved to a type
ERROR: /development/android/frameworks/support/v4/java/android/support/v4/content/ContentResolverCompat.java:19: The import android.accounts cannot be resolved
ERROR: /development/android/frameworks/support/v4/java/android/support/v4/content/ContentResolverCompat.java:137: Account cannot be resolved to a type
ERROR: /development/android/frameworks/support/v4/java/android/support/v4/content/ContentResolverCompat.java:138: android.content.SyncStatusInfo cannot be resolved to a type
ERROR: /development/android/frameworks/support/v4/java/android/support/v4/content/ContentResolverCompat.java:146: Account cannot be resolved to a type
ERROR: /development/android/frameworks/support/v4/java/android/support/v4/content/ContentResolverCompat.java:148: android.content.SyncStatusInfo cannot be resolved to a type
My thought was that #hide is a documentation thing only and I can access it from within AOSP classes. But why I can't build my changes when I want to access hidden classes / methods?
Note: I don't want to build an Android app, I want to change / build the Android source code itself.
Edit: This isn't a duplicate of #hide class not found because #hide means that it is removed from JavaDoc but it is still accessible from Android source code itself.
I recently added a library to my app ('GNSDK' by Gracenote) and am now trying to build the app for release using Proguard. I successfully built and installed the release version of the app once, but all subsequent attempts produce this error:
Unexpected error while evaluating instruction:
Class = [com/gracenote/gnsdk/GnManager]
Method = [<init>(Landroid/content/Context;Ljava/lang/String;I)V]
Instruction = [87] getfield #120
Exception = [java.lang.IllegalArgumentException] (Value "i" is not a
reference value [proguard.evaluation.value.UnknownIntegerValue])
Unexpected error while performing partial evaluation:
Class = [com/gracenote/gnsdk/GnManager]
Method = [<init>(Landroid/content/Context;Ljava/lang/String;I)V]
Exception = [java.lang.IllegalArgumentException] (Value "i" is not a reference value [proguard.evaluation.value.UnknownIntegerValue])
:app:proguardBetaRelease FAILED
Error:Execution failed for task ':app:proguardBetaRelease'.
Value "i" is not a reference value [proguard.evaluation.value.UnknownIntegerValue]`
I tried to force proguard to leave the library alone (since that's the only difference between the debug and release builds) with:
-keep class com.gracenote.** {
*;
}
but it does not seem to make a difference.
Any hints on how to debug or track down this error? I am not sure why the constructor of com.gracenote.gnsdk.GnManager would be failing. The error makes it sound like it is getting an invalid input.
I'm using Android Studio 1.4, build tools 23.0.0.
I found that this is a bug in Proguard: https://sourceforge.net/p/proguard/bugs/573/
Looks like it will be released soon. In the meantime, you can work around by adding:
-optimizations !class/unboxing/enum
to your proguard file.
For what it's worth, I found this for a java project. I was running proguard targeting 1.8 when it should have been 1.9. Once I changed it it worked.
I'm currently building an android application using ANT on a Jenkins server.
DexGuard is set to run on release in the custom_rules.xml.
Currently there is an issue when DexGuard tries to convert a method:
[dexguard] Unexpected error while converting:
[dexguard] Class = [o/?]
[dexguard] Method = [?(Ljava/lang/String;)Lo/?;]
[dexguard] Exception = [java.lang.IllegalStateException] (Variable v17 too large for instruction [neg-int v17, v17])
[dexguard] java.lang.IllegalStateException: Variable v17 too large for instruction [neg-int v17, v17]
...
Stack trace
...
[dexguard] Not converting this method
My question is, is there a way to get DexGuard to exit with an error status so that either ANT or Jenkins can mark the build as failed?
At the moment it simply prints the stack trace and continues.
I am currently using the Text-finder plugin for Jenkins as a post build step to match a DexGuard exception. If found it downgrades the build to failed.
DexGuard currently ignores methods that it can't convert from Java bytecode to Dalvik bytecode, for any reason -- notably corrupt input code. In this case, it looks more like a bug in DexGuard itself. We'll fix it as soon as possible, and we'll consider adding a flag to stop with an error status.
(I am the lead developer of ProGuard and DexGuard)