I encountered a problem when using Proguard(version 6.0.3) in my android project.
Below is the stack of exceptions:(I am sorry that some code info of our program was replaceed by xxx/a/)
Ignoring unused library classes...
Original number of library classes: 6448
Final number of library classes: 2187
Printing kept classes, fields, and methods...
Inlining subroutines...
Obfuscating...
Printing mapping to [/root/workspace/xxx/build/outputs/mapping/xxx/release/mapping.txt]...
Preverifying...
Unexpected error while performing partial evaluation:
Class = [xxx/a/b]
Method = [a(Ljava/lang/String;)V]
Exception = [java.lang.IllegalArgumentException] (Can't find common super class of [xxx/a/c] (with 1 known super classes) and [java/util/List] (with 2 known super classes))
Unexpected error while preverifying:
First of all,i guess that there must be something wrong with my compilation(such as modify our program classes) or a bug of proguard in obfuscating process(we had turned off optimization )。So i tried to modify proguard and add a preverifying process before obfuscating ,below is the changes:
public void execute() throws IOException
{
...
readInput();
...
if (configuration.addConfigurationDebugging)
{
addConfigurationLogging();
}
//**********added*************
if (configuration.preverify)
{
preverify();
}
if (configuration.printSeeds != null)
{
printSeeds();
}
...
if (configuration.preverify)
{
preverify();
}
....
}
And i ran compilation again and the exceptiion(stack is same as before) still occured.
Ignoring unused library classes...
Original number of library classes: 6448
Final number of library classes: 2187
Preverifying...
Can't find common super class of [xxx/a/c] (with 1 known super classes) and [java/util/List] (with 2 known super classes)
0 aload_1 v1 popCount 0 pushCount 1 inst lenth 1
1 ldc #214 popCount 0 pushCount 1 inst lenth 2
3 invokestatic #49 popCount 2 pushCount 0 inst lenth 3
6 aload_0 v0 popCount 0 pushCount 1 inst lenth 1
7 aload_1 v1 popCount 0 pushCount 1 inst lenth 1
8 putfield #75 popCount 2 pushCount 0 inst lenth 3
11 aload_0 v0 popCount 0 pushCount 1 inst lenth 1
12 getfield #19 popCount 1 pushCount 1 inst lenth 3
15 checkcast #29 popCount 1 pushCount 1 inst lenth 3
18 dup popCount 1 pushCount 2 inst lenth 1
19 ifnull +18 popCount 1 pushCount 0 inst lenth 3
22 invokevirtual #32 popCount 1 pushCount 1 inst lenth 3
25 dup popCount 1 pushCount 2 inst lenth 1
26 ifnull +11 popCount 1 pushCount 0 inst lenth 3
29 invokeinterface #217, 256 popCount 1 pushCount 0 inst lenth 5
34 goto +4 popCount 0 pushCount 0 inst lenth 3
37 pop popCount 1 pushCount 0 inst lenth 1
38 aload_0 v0 popCount 0 pushCount 1 inst lenth 1
39 iconst_0 popCount 0 pushCount 1 inst lenth 1
40 putfield #83 popCount 2 pushCount 0 inst lenth 3
43 return popCount 0 pushCount 0 inst lenth 1
Unexpected error while performing partial evaluation:
Class = [xxx/a/b]
Method = [restore(Ljava/lang/String;)V]
Exception = [java.lang.IllegalArgumentException] (Can't find common super class of [xxx/a/c] (with 1 known super classes) and [java/util/List] (with 2 known super classes))
Unexpected error while preverifying:
Note:I have changed code of proguard and print the bytecode of method while exception occured
According to the log,we could find the location where the exception throwed:
/**
* Returns the most specific common superclass or interface of the given
* classes.
* @param class1 the first class.
* @param class2 the second class.
* @param interfaces specifies whether to look for a superclass or for an
* interface.
* @return the common class.
*/
private Clazz findCommonClass(Clazz class1,
Clazz class2,
boolean interfaces)
{
// Collect the superclasses or the interfaces of this class.
...
if (commonClass == null)
{
throw new IllegalArgumentException("Can't find common super class of ["+
class1.getName() +"] (with "+superClasses1Count +" known super classes) and ["+
class2.getName()+"] (with "+superClasses2Count+" known super classes)");
}
...
return commonClass;
}
I was shocked that why preverifier goes to find common super class bettwen xxx/a/c and java/util/List
So, there should be a problem with the bytecode(location:xxx/a/b.restore) before proguard and i found the class.Here is the bytecode(before as a program input) of method 'xxx/a/b.restore':
// access flags 0x11
public final restore(Ljava/lang/String;)V
// annotable parameter count: 1 (invisible)
@Lorg/jetbrains/annotations/NotNull;() // invisible, parameter 0
L0
ALOAD 1
LDC "requestId"
INVOKESTATIC kotlin/jvm/internal/Intrinsics.checkParameterIsNotNull (Ljava/lang/Object;Ljava/lang/String;)V
L1
LINENUMBER 105 L1
ALOAD 0
ALOAD 1
PUTFIELD xxx/a/b.requestSessionId : Ljava/lang/String;
L2
LINENUMBER 106 L2
ALOAD 0
GETFIELD xxx/a/b.mData : Ljava/lang/Object;
CHECKCAST xxx/a/c
DUP
IFNULL L3
INVOKEVIRTUAL xxx/a/c.getAwemeList ()Ljava/util/List;
DUP
IFNULL L3
INVOKEINTERFACE java/util/List.clear ()V (itf)
GOTO L4
L3
FRAME SAME1 java/lang/Object
POP
L4
LINENUMBER 107 L4
FRAME SAME
ALOAD 0
ICONST_0
PUTFIELD xxx/a/b.mCursor : I
L5
LINENUMBER 108 L5
RETURN
L6
LOCALVARIABLE this Lxxx/a/b; L0 L6 0
LOCALVARIABLE requestId Ljava/lang/String; L0 L6 1
MAXSTACK = 2
MAXLOCALS = 2
The source code was writtern by koltin and much like below:
package xxx.a
class b:d<c>(){
...
104 fun restore(requestId: String) {
105 requestSessionId = requestId
106 mData?.awemeList?.clear()
107 mCursor = 0
108 }
...
}
And then,i had tried to find something bad within the bytecode but everything is legall.
And then,i had tried to find something different bytecode bettwen the xxx/a/b.restore and the outcome of kotlin compilation but it is no different(Around java/util/List),Below is the outcome bytecode of kotlin compilation:
// access flags 0x11
public final restore(Ljava/lang/String;)V
// annotable parameter count: 1 (visible)
// annotable parameter count: 1 (invisible)
@Lorg/jetbrains/annotations/NotNull;() // invisible, parameter 0
L0
ALOAD 1
LDC "requestId"
INVOKESTATIC kotlin/jvm/internal/Intrinsics.checkParameterIsNotNull (Ljava/lang/Object;Ljava/lang/String;)V
L1
LINENUMBER 105 L1
ALOAD 0
ALOAD 1
PUTFIELD xxx/a/b.requestSessionId : Ljava/lang/String;
L2
LINENUMBER 106 L2
ALOAD 0
GETFIELD xxx/a/b.mData : Ljava/lang/Object;
CHECKCAST xxx/a/c
DUP
IFNULL L3
INVOKEVIRTUAL xxx/a/c.getAwemeList ()Ljava/util/List;
DUP
IFNULL L3
INVOKEINTERFACE java/util/List.clear ()V (itf)
GOTO L4
L3
POP
L4
L5
LINENUMBER 107 L5
ALOAD 0
ICONST_0
PUTFIELD xxx/a/b.mCursor : I
L6
LINENUMBER 108 L6
RETURN
L7
LOCALVARIABLE this Lxxx/a/b; L0 L7 0
LOCALVARIABLE requestId Ljava/lang/String; L0 L7 1
MAXSTACK = 2
MAXLOCALS = 2

And then,i guessed It's a bug in the verification process .I tried to turned off verification and ran on my app and found tha the app was working fine,with no crash.
So,i think it is a bug of proguard。
Note:I have tried the latest version(6.2.0) and it still no work.
link of diff image:https://s2.ax1x.com/2019/10/12/uOWzpq.png
Last edit: Mr Yang 2019-10-12
Thank you for your extensive research. This error typically occurs if ProGuard doesn't have the complete class hierarchy of all classes that are processed. Have you suppressed any warnings with
-dontwarnor-ignorewarnings? Can you run ProGuard without these settings? If you get warnings about missing classes, can you add their jars to the input?See https://www.guardsquare.com/en/products/proguard/manual/troubleshooting#superclass
Closing this issue.
Please also note that when using ProGuard for an android project, there is no need for preverification, so you should add -dontpreverify in your configuration which probably also avoid the problem.