Android Proguard failing with "Value 'i' is not a reference value" - android

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.

Related

Proguard Overflow of unsigned short value

After adding a jar file containing some functionality that I need to my application, my proguard build hasn't been working. the error message I get after running my proguard build is:
Warning: Exception while processing task java.io.IOException: java.lang.RuntimeException: Unexpected error while writing class [proguard/optimize/gson/_OptimizedTypeAdapterFactory] (Overflow of unsigned short value [93362])
Thread(Tasks limiter_1): destruction
Is there any way to exclude that jar file from being checked by ProGuard? I'm using ProGuard v6.2.2. I suspected the issue would be GSON since i had issues with it before this error.
I've also checked and researched answers here such as Proguard [ java.lang.IllegalArgumentException: Overflow of unsigned short value ]
Android crash while using GSON Library and ProGuard
#732 Exception while handling very long string argument
Any help would be appreciated.
You can read more about ProGuard configuration and optimizations here:
https://www.guardsquare.com/en/products/proguard/manual/usage/optimizations
but in your case you can exclude the gson library that is throwing the exception like this:
-optimizations !library/gson
That's a known bug. Until this had been rectified, you can only disable the code optimization:
-optimizations !code/simplification/string
Or disable optimization altogether with -dontoptimize. Or just use R8 instead ...
That one linked answer which suggests a version-downgrade might also work.

Warning: can't find referenced method 'int save(int)' in library class android.graphics.Canvas

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.

Android build fails with kotlin-reflect and proguard

I am unable to build my release product if I include kotlin-reflect with it. I attempted adding this to proguard configuration:
-keep class kotlin.reflect.** { *; }
But it did not help at all. Here is the error result from the gradle build:
Optimizing...
Unexpected error while performing partial evaluation:
Class = [kotlin/reflect/jvm/internal/impl/renderer/DescriptorRendererImpl]
Method = [renderPossiblyInnerType(Ljava/lang/StringBuilder;Lkotlin/reflect/jvm/internal/impl/descriptors/PossiblyInnerType;)V]
Exception = [java.lang.IllegalArgumentException] (Stacks have different current sizes [0] and [1])
Warning: Exception while processing task java.io.IOException: java.lang.IllegalArgumentException: Stacks have different current sizes [0] and [1]
I am using kotlin 1.1.1 (and gradle 3.3, if that matters.)
j
I had some similar errors with kotlin reflect class and proguard, solved adding in the -optimizations
!class/unboxing/enum
My bug was related to this Android Proguard failing with "Value 'i' is not a reference value"
and found the fix in one of the comments

Is there a way to make DexGuard exit with an error condition if an error occurs?

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)

Conversion To Dalvik format Exception : Invalid dex bytecode offset

I am getting the following error when trying to run my code with ADT v21 using Eclipse Juno.
[2013-05-28 10:08:39 - XYZ] Dx
EXCEPTION FROM SIMULATION:
[2013-05-28 10:08:39 - XYZ] Dx local 000c: invalid
[2013-05-28 10:08:39 - XYZ] Dx ...at bytecode offset 00000c80
locals[0000]: Lcom/sec/x/y/z;
locals[0001]: I
locals[0002]: I
locals[0003]: Landroid/content/Intent;
locals[0004]: Ljava/lang/String;
locals[0005]: invalid
locals[0006]: Ljava/lang/String;
locals[0007]: invalid
locals[0008]: invalid
locals[0009]: invalid
locals[000a]: invalid
locals[000b]: Ljava/lang/String;
locals[000c]: invalid
locals[000d]: invalid
locals[000e]: invalid
locals[000f]: invalid
locals[0010]: invalid
locals[0011]: invalid
...while working on block 0c80
...while working on method onActivityResult IILandroid/content/Intent V
...while processing onActivityResult (IILandroid/content/Intent V
...while processing com/sec/x/y/z.class
[2013-05-28 10:09:05 - XYZ] Dx 1 error; aborting
[2013-05-28 10:09:05 - XYZ] Conversion to Dalvik format failed with error 1
This project builds perfectly on ADT v20 and below. But it is consistently giving the same error with ADT v21. The error does not occur in build stage. It occurs when I try to run the application using Eclipse.
I have read thousands of threads related to this. And none of them are working. This is not a "Clean/Build" issue for sure.
To me it seems like an Eclipse or Proguard issue. I have wasted alomst 12 hours of my life on this. Please somebody save me. Anyone with any clue on this?
"locals invalid ... Conversion to Dalvik format failed with error 1" may be caused by ProGuard's optimization step, which can't always keep the debug information about local variables consistent with the optimizations on the code.
You can avoid it by not keeping this debug information (don't specify -keepattributes LocalVariableTable).
You can work around it by disabling optimization (add -dontoptimize to your proguard-project.txt).
You can check if the most recent version of ProGuard solves the problem (replace android-sdk/tools/proguard/lib/proguard.jar with the latest version from the ProGuard site).
If updating to the latest version of ProGuard doesn't help, you can report a bug.
I resolved it myself. In onActivityResult ( where this error was getting thrown ) in one place I was not initializing an Integer variable. By initializing it, the issue got resolved. Very weird. If anyone can explain this appropriately, I'll recomend his/her answer.
Before:
int x;
After
int x = 0;
Thats it!
I think eclipse failed to recognized that initialize local variable before using it. So It does not showing warning to user while writing the code. But adt failed to compile file.
According to TanDroiD if you initialize variable your problem will be solved.
I had a similar issue, the solution was to put in a -keep class into the proguard config for the causing class. In my situation it was a class from the Fabric (Crashlytics library)
-keep class io.fabric.sdk.android.services.concurrency.DependencyPriorityBlockingQueue { *; }

Categories

Resources