как исправить предупреждение proguard «не могу найти указанный метод» для существующих методов «clone» и «finalize» класса java.lang.Object

Я пытаюсь сжать приложение для Android, которое потребляет ical4j.jar.

Когда я создаю apk с помощью proguard, используя gradle proguardDebug, я получаю

  • 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()

Я уже подтвердил, что android-7 поддерживает finalize() и clone(): "... \ Android ... \ sdk \ platform \ android-7 \ android.jar" имеет методы finalize() и clone() в классе java.lang.Object.

Ты хоть представляешь, как это исправить?

Примечание: это не дубликат других вопросов «proguard не может найти ссылочный метод», потому что в моем конкретном случае я думаю, что отсутствующий метод должен быть там.

Я использую

  • proguard-4.11 с
  • gradle-1.11
    • Groovy: 1.8.6
    • Ant: Apache Ant (TM) версии 1.9.2, скомпилированный 8 июля 2013 г.
    • Плющ: 2.2.0
    • JVM: 1.7.0_25 (Oracle Corporation 23.25-b01)
    • ОС: Windows 7 6.1 amd64
  • ical4j.jar 1.0.5

это конфигурация proguard proguard-rules.txt, которая, вероятно, нуждается в исправлении:

#  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.**

Это мой 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'
    }

[Обновление 2014-12-20]

Я добавил свою рабочую конфигурацию в ответ ниже.

Примечание. В текущей версии Android Studio 1.0 (android.buildToolsVersion> = '20') вы должны заменить runProguard на minifyEnabled.

Пример

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

person k3b    schedule 27.05.2014    source источник


Ответы (3)


net.fortuna.ical4j.model.CalendarFactory расширяет groovy.util.AbstractFactory, который расширяет java.lang.Object. Однако средний класс отсутствует в вашем вводе (вы подавляете соответствующие предупреждения с помощью -dontwarn). Поскольку часть иерархии классов отсутствует, ProGuard не понимает, что CalendarFactory может получить доступ к защищенным методам clone и finalize, и выводит эти предупреждения.

Поскольку ваш код, вероятно, вообще не использует класс, вы можете подавить предупреждения:

-dontwarn net.fortuna.ical4j.model.CalendarFactory

Или для покрытия всех подобных классов:

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

Вы не должны добавлять никаких опций -keep для этой проблемы; Android SDK уже определяет для вас основные параметры, связанные с Android.

person Eric Lafortune    schedule 29.05.2014
comment
Я удалил, как было предложено -keep class net.fortuna.ical4j.model.** { *; }, что еще больше уменьшило apk на дополнительные 60 кб. к счастью, мое приложение для Android не использует никаких зависимых от Groovy классов. Я обновил свой ответ окончательным решением - person k3b; 30.05.2014

Это мой конфиг-файл прогарда. Попробуйте скопировать и вставить

-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); 
}

Затем добавьте свой код, как показано ниже: При использовании

-dontwarn groovy.**

также добавить

-keep class groovy.** { *; }

Сделайте это для всех внешних библиотек.

person Dawid C    schedule 28.05.2014
comment
Спасибо за ответ. Я попытался добавить вашу конфигурацию, но результат был тем же ошибкой. большинство специальных правил для Android, например -keep public class * extends android.app.Activity, должны исходить от Android/.../tools/proguard/proguard-android(-optimize).txt - person k3b; 28.05.2014
comment
вы пробовали использовать класс -keep? Я знаю, что в моем файле используются все специальные правила Android. Вы можете попробовать отключить эти системные правила, удалив $ {sdk.dir} /tools/proguard/proguard-android.txt из файла project.properties (то есть, когда вы используете eclipse) - person Dawid C; 28.05.2014
comment
Я не использовал Keep для Groovy-части, потому что я не хочу сохранять Groovy-часть библиотеки. Однако я использую сохранение в моем текущем обходном пути. Я проголосовал за этот ответ от -1 до 0, потому что он мне очень помог, хотя это не было решением - person k3b; 28.05.2014

[обновление 2014-05-30 переформулировка этого текста]

Спасибо за ответ @EricLafortune, который помог мне понять и решить проблему.

Для тех, кто хочет сжать приложения для Android ical4j, вот мое рабочее решение:

все классы с in library class java.lang.Object - проблемой из пространства имен

 net.fortuna.ical4j.model.**

поэтому я добавил эти строки в proguard-rules.txt

###################
# Get rid of #can't find referenced method in library class java.lang.Object# warnings for clone() and finalize()
# for details see http://stackoverflow.com/questions/23883028/how-to-fix-proguard-warning-cant-find-referenced-method-for-existing-methods
-dontwarn net.fortuna.ical4j.model.**

###############
# I use proguard only to remove unused stuff and to keep the app small.
# I donot want to obfuscate (rename packages, classes, methods, ...) since this is open source
-keepnames class ** { *; }
-keepnames interface ** { *; }
-keepnames enum ** { *; }

статистика:

  • без обфускации: 932 класса; apk 911кб.
  • с обфускацией: 365 классов; apk 505кб
person k3b    schedule 28.05.2014
comment
Если вам не нужно / вы не хотите обфускации, есть вариант: -dontobfuscate, который вы можете использовать. - person Pelpotronic; 28.08.2015