Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how to fix proguard warning 'can't find referenced method' for existing methods 'clone' and 'finalize' of class java.lang.Object

I try to compress an android app that consumes ical4j.jar.

When i build the apk with proguard using gradle proguardDebug i get

  • Warning: net.fortuna.ical4j.model.CalendarFactory: can't find referenced method 'void finalize()' in library class java.lang.Object
    • 6 additional similar warnings for finalize()
  • Warning: net.fortuna.ical4j.model.CalendarFactory: can't find referenced method 'java.lang.Object clone()' in library class java.lang.Object
    • 6 additional similar warnings for clone()

I already verified that android-7 supports finalize() and clone(): "...\Android...\sdk\platforms\android-7\android.jar" has methods finalize() and clone() in class java.lang.Object .

Do you have any idea how to fix this?

Note: this is not a duplicate of other 'proguard can't find referenced method' questions because in my specific case i think that the missing method should be there.

I am using

  • proguard-4.11 with
  • gradle-1.11
    • Groovy: 1.8.6
    • Ant: Apache Ant(TM) version 1.9.2 compiled on July 8 2013
    • Ivy: 2.2.0
    • JVM: 1.7.0_25 (Oracle Corporation 23.25-b01)
    • OS: Windows 7 6.1 amd64
  • ical4j.jar 1.0.5

this is proguard config proguard-rules.txt that probably need some fix:

#  proguard-rules.txt
## ical4j also contains groovy code which is not used in android 
-dontwarn groovy.**
-dontwarn org.codehaus.groovy.**
-dontwarn org.apache.commons.logging.**
-dontwarn sun.misc.Perf

-dontnote com.google.vending.**
-dontnote com.android.vending.licensing.**

This is my build.gradle

    buildscript {
        repositories {
            mavenCentral()
        }
        dependencies {
            classpath 'com.android.tools.build:gradle:0.9.+'
            classpath 'net.sf.proguard:proguard-gradle:4.11'
        }
    }

    allprojects {
        repositories {
            mavenCentral()
        }
    }

    apply plugin: 'android'

    configurations {
        compile.exclude group: 'commons-logging' // referenced in some portable lib. use androids internal instead
    }

    android {
        compileSdkVersion 19
        buildToolsVersion '19.0.3'

        packagingOptions {
            exclude 'META-INF/LICENSE.txt'
            exclude 'META-INF/NOTICE.txt'
        }

        defaultConfig {
            minSdkVersion 7
            targetSdkVersion 19
        }

        buildTypes {
            release {
                runProguard false
                proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt'
            }

            // used for testing. remove if it works as expected
            debug {
                runProguard true
                proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt'
            }
        }
    }

    dependencies {
        compile 'org.mnode.ical4j:ical4j:1.0.5'
        compile 'backport-util-concurrent:backport-util-concurrent:3.1'
        compile 'commons-codec:commons-codec:1.8'
        compile 'commons-lang:commons-lang:2.6'
    }

[Update 2014-12-20]

I have added my working configuration as answer below.

Note: with Current Android Studio 1.0 (android.buildToolsVersion >= '20') you must replace runProguard with minifyEnabled

Example

    android {
        buildTypes {
            release {
                minifyEnabled true
                proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt'
            }
    }
like image 606
k3b Avatar asked May 27 '14 07:05

k3b


2 Answers

net.fortuna.ical4j.model.CalendarFactory extends groovy.util.AbstractFactory which extends java.lang.Object. However, the middle class is missing from your input (you're suppressing the corresponding warnings with -dontwarn). With part of the class hierarchy missing, ProGuard doesn't realize that CalendarFactory may access the protected methods clone and finalize, and it prints out these warnings.

Since your code probably doesn't use the class at all, you can suppress the warnings:

-dontwarn net.fortuna.ical4j.model.CalendarFactory

Or for covering all similar classes:

-dontwarn net.fortuna.ical4j.model.**

You shouldn't add any -keep options for this issue; the Android SDK already specifies the basic Android-related -keep options for you.

like image 183
Eric Lafortune Avatar answered Nov 04 '22 21:11

Eric Lafortune


This is my proguard config-file. Try copy-paste it

-dontskipnonpubliclibraryclasses
-dontskipnonpubliclibraryclassmembers
-dontpreverify
-verbose    

# standard, except v4.app.Fragment, its required when app uses Fragments

-keep public class * extends android.app.Activity
-keep public class * extends android.support.v7.app.ActionBarActivity
-keep public class * extends android.support.v4.app.Fragment
-keep public class * extends android.app.Application
-keep public class * extends android.app.Service
-keep public class * extends android.content.BroadcastReceiver
-keep public class * extends android.content.ContentProvider

-keepclasseswithmembers class * {
    native <methods>;
}

-keepclasseswithmembers class * {
    public <init>(android.content.Context, android.util.AttributeSet);
}

-keepclasseswithmembers class * {
    public <init>(android.content.Context, android.util.AttributeSet, int);
}

-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 * extends android.app.Activity { 
       public void *(android.view.View); 
}

Then add your code, as following: When using

-dontwarn groovy.**

also add

-keep class groovy.** { *; }

Do it for all external libraries.

like image 43
Dawid C Avatar answered Nov 04 '22 20:11

Dawid C