Proguard, похоже, удаляет целые пакеты, которые включены в путь

Я использую Proguard для обфускации моего кода и уменьшаю его. Я строю с помощью Eclipse и имею некоторое время. Недавно у меня была сборка, которая отлично работает в отладочной версии, которую я пытаюсь выпустить. Я пытался сделать это в течение большей части последнего дня, и я продолжаю получать следующую ошибку, когда пытаюсь запустить свой код с помощью выпущенной сборки (я могу создать больше, если это поможет).

02-25 16: 39: 58.844: E/AndroidRuntime (27593): вызвано: java.lang.ClassNotFoundException: не нашел класс "com.kd7uiy.hamfinder.MainActivity" по пути: DexPathList [[zip файл "/data/app/com.kd7uiy.hamfinder-2.apk" ],nativeLibraryDirectories=[/data/app-lib/com.kd7uiy.hamfinder-2, /vendor/lib,/system/lib]]

По-настоящему странно, я не изменил свой файл proguard, по крайней мере, не в первый раз, когда я это сделал. С тех пор я играл с ним, чтобы узнать, могу ли я получить что-нибудь, чтобы заставить его работать, но ничего похожего на этот трюк. Начиная с этой сборки, я добавил новую библиотеку в свою базу кода, утилиту Google Maps. Моя последняя сборка была всего несколько дней назад.

Попытка устранить эту проблему, я обнаружил, что существует целая папка, которая не отображается в списке путей. Я вижу эту папку в скомпилированных двоичных классах, но они не выживают. Если я перестану использовать Proguard, версия выпуска будет работать по назначению.

Мой код использует 6 пакетов, которые находятся в моем каталоге /src. Я существенно не изменил эту структуру для этой версии, хотя я, вероятно, добавил файл или два в разные папки и, возможно, переместил папку или две. Эти 6 пакетов:

com.kd7uiy.hamfinder
com.kd7uiy.hamfinder.dialogs
com.kd7uiy.hamfinder.ObserverOutPairs
com.kd7uiy.hamfinder.Subjects
com.kd7uiy.library
com.robobunny

Из них я не могу найти прямых доказательств следующих пакетов в файле сопоставления proguard, по крайней мере для этого конкретного процесса

com.kd7uiy.hamfinder
com.kd7uiy.hamfinder.ObserverOutPairs
com.kd7uiy.hamfinder.Subjects

У некоторых есть несколько имен переменных, на которые ссылаются, но не доказательства включения всего пакета. Я проверил файл .dex, который также не содержит недостающие пакеты. Я должен добавить, иногда, по-видимому, случайным образом некоторые из других пакетов, но никогда не com.kd7uiy.hamfinder, где находится моя MainActivity. Иногда никто из них не появляется.

Здесь мой файл project.properties:

# To enable ProGuard to shrink and obfuscate your code, uncomment this (available properties: sdk.dir, user.home):
proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt

# Project target.
target=android-19
android.library.reference.1=..\\..\\..\\Documents\\GitHub\\android-maps-utils\\library
android.library.reference.2=..\\..\\..\\..\\..\\Program Files (x86)\\Android\\android-sdk\\extras\\android\\support\\v7\\appcompat
android.library.reference.3=..\\..\\..\\..\\..\\Program Files (x86)\\Android\\android-sdk\\extras\\google\\google_play_services\\libproject\\google-play-services_lib
android.library.reference.4=..\\..\\..\\Documents\\GitHub\\android-styled-dialogs\\library\\src\\main
android.library.reference.5=..\\..\\..\\Documents\\GitHub\\drag-sort-listview\\library

И мой оригинальный файл proguard-project.txt, который, как было показано, не работает.

-keep class com.kd7uiy.hamfinder.MainSettingsActivity$GeneralPreferenceFragment
-keep class com.kd7uiy.hamfinder.MainSettingsActivity$LocationPreferenceFragment
-keep class com.android.vending.billing.**
-keep class jsqlite.** { *;}
-ignorewarnings

Я изменил его, чтобы добавить соответствующие изменения в Google Maps для Proguard. Ничего не работало.

-keep class com.kd7uiy.hamfinder.MainSettingsActivity$GeneralPreferenceFragment
-keep class com.kd7uiy.hamfinder.MainSettingsActivity$LocationPreferenceFragment
-keep class com.android.vending.billing.**
-keep class jsqlite.** { *;}
-keep class * extends java.util.ListResourceBundle {
    protected Object[][] getContents();
}

-keep public class com.google.android.gms.common.internal.safeparcel.SafeParcelable {
    public static final *** NULL;
}

-keepnames @com.google.android.gms.common.annotation.KeepName class *
-keepclassmembernames class * {
    @com.google.android.gms.common.annotation.KeepName *;
}

-keepnames class * implements android.os.Parcelable {
    public static final ** CREATOR;
}

#-keep class com.kd7uiy.hamfinder.AbstractReverseGeoCoder
-keep class com.kd7uiy.hamfinder.AbstractWebReverseGeoCoder

-dontwarn java.awt.**

-ignorewarnings

Для справки здесь мой файл proguard-android.txt находится в правильном месте.

# This is a configuration file for ProGuard.
# http://proguard.sourceforge.net/index.html#manual/usage.html

-dontusemixedcaseclassnames
-dontskipnonpubliclibraryclasses
-verbose

# Optimization is turned off by default. Dex does not like code run
# through the ProGuard optimize and preverify steps (and performs some
# of these optimizations on its own).
-dontoptimize
-dontpreverify
# Note that if you want to enable optimization, you cannot just
# include optimization flags in your own project configuration file;
# instead you will need to point to the
# "proguard-android-optimize.txt" file instead of this one from your
# project.properties file.

-keepattributes *Annotation*
-keep public class com.google.vending.licensing.ILicensingService
-keep public class com.android.vending.licensing.ILicensingService

# For native methods, see http://proguard.sourceforge.net/manual/examples.html#native
-keepclasseswithmembernames class * {
    native <methods>;
}

# keep setters in Views so that animations can still work.
# see http://proguard.sourceforge.net/manual/examples.html#beans
-keepclassmembers public class * extends android.view.View {
   void set*(***);
   *** get*();
}

# We want to keep methods in Activity that could be used in the XML attribute onClick
-keepclassmembers class * extends android.app.Activity {
   public void *(android.view.View);
}

# For enumeration classes, see http://proguard.sourceforge.net/manual/examples.html#enumerations
-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 **.R$* {
    public static <fields>;
}

# The support library contains references to newer platform versions.
# Don't warn about those in case this app is linking against an older
# platform version.  We know about them, and they are safe.
-dontwarn android.support.**

Здесь снимок моих файлов

enter image description here

И вот мой путь сборки

enter image description here

Посмотрев на другие файлы, я видел доказательства файлов в файле /bin/proguard.txt, но после этого они просто исчезают. Скомпилированный размер также заметно меньше, но это может быть связано с тем, что у меня гораздо больше не кодов, чем у кода, было бы трудно обнаружить разницу в нескольких java файлах. Здесь весь файл /bin/proguard.txt.

# view res/layout/activity_main.xml #generated:14
-keep class android.support.v4.view.ViewPager { <init>(...); }

# view large-land\res/layout-large-land/activity_main.xml #generated:2
# view large-port\res/layout-large-port/activity_main.xml #generated:2
# view res/layout/activity_main.xml #generated:1
# view xlarge-land\res/layout-xlarge-land/activity_main.xml #generated:2
# view xlarge-port\res/layout-xlarge-port/activity_main.xml #generated:2
-keep class android.support.v4.widget.DrawerLayout { <init>(...); }

# view res/layout/abc_action_menu_item_layout.xml #generated:17
-keep class android.support.v7.internal.view.menu.ActionMenuItemView { <init>(...); }

# view res/layout/abc_action_menu_layout.xml #generated:17
-keep class android.support.v7.internal.view.menu.ActionMenuView { <init>(...); }

# view res/layout/abc_expanded_menu_layout.xml #generated:17
-keep class android.support.v7.internal.view.menu.ExpandedMenuView { <init>(...); }

# view res/layout/abc_list_menu_item_layout.xml #generated:17
# view res/layout/abc_popup_menu_item_layout.xml #generated:17
-keep class android.support.v7.internal.view.menu.ListMenuItemView { <init>(...); }

# view res/layout/abc_action_bar_decor_include.xml #generated:19
# view res/layout/abc_action_bar_decor_include.xml #generated:47
# view res/layout/abc_action_bar_decor_overlay.xml #generated:30
# view res/layout/abc_action_bar_decor_overlay.xml #generated:53
-keep class android.support.v7.internal.widget.ActionBarContainer { <init>(...); }

# view res/layout/abc_action_bar_decor_include.xml #generated:31
# view res/layout/abc_action_bar_decor_overlay.xml #generated:41
# view res/layout/abc_action_mode_bar.xml #generated:19
-keep class android.support.v7.internal.widget.ActionBarContextView { <init>(...); }

# view res/layout/abc_action_bar_decor_overlay.xml #generated:17
-keep class android.support.v7.internal.widget.ActionBarOverlayLayout { <init>(...); }

# view res/layout/abc_action_bar_decor_include.xml #generated:25
# view res/layout/abc_action_bar_decor_overlay.xml #generated:36
-keep class android.support.v7.internal.widget.ActionBarView { <init>(...); }

# view res/layout/abc_action_bar_home.xml #generated:17
-keep class android.support.v7.internal.widget.ActionBarView$HomeView { <init>(...); }

# view res/layout/abc_action_bar_tabbar.xml #generated:17
# view res/layout/abc_activity_chooser_view.xml #generated:19
-keep class android.support.v7.internal.widget.LinearLayoutICS { <init>(...); }

# view v11\res/layout-v11/abc_action_bar_decor.xml #generated:17
-keep class android.support.v7.internal.widget.NativeActionModeAwareLayout { <init>(...); }

# view res/layout/abc_action_bar_tab.xml #generated:17
-keep class android.support.v7.internal.widget.ScrollingTabContainerView$TabView { <init>(...); }

# view res/layout/abc_search_view.xml #generated:85
-keep class android.support.v7.widget.SearchView$SearchAutoComplete { <init>(...); }

# view AndroidManifest.xml #generated:72
-keep class com.google.analytics.tracking.android.CampaignTrackingReceiver { <init>(...); }

# view AndroidManifest.xml #generated:70
-keep class com.google.analytics.tracking.android.CampaignTrackingService { <init>(...); }

# view AndroidManifest.xml #generated:56
-keep class com.google.android.gms.ads.AdActivity { <init>(...); }

# view large-land\res/layout-large-land/activity_main.xml #generated:13
# view large-port\res/layout-large-port/activity_main.xml #generated:13
# view res/layout/activity_main.xml #generated:26
# view xlarge-land\res/layout-xlarge-land/activity_main.xml #generated:13
# view xlarge-port\res/layout-xlarge-port/activity_main.xml #generated:15
-keep class com.google.android.gms.ads.AdView { <init>(...); }

# view res/layout/google_map_dialog_preference.xml #generated:7
-keep class com.google.android.gms.maps.MapFragment { <init>(...); }

# view res/layout/google_map.xml #generated:2
# view res/layout/google_map_support_dialog_preference.xml #generated:7
-keep class com.google.android.gms.maps.SupportMapFragment { <init>(...); }

# view res/layout/text_bubble.xml #generated:8
-keep class com.google.maps.android.ui.RotationLayout { <init>(...); }

# view large-land\res/layout-large-land/activity_main.xml #generated:24
# view large-port\res/layout-large-port/activity_main.xml #generated:24
# view xlarge-land\res/layout-xlarge-land/activity_main.xml #generated:24
# view xlarge-port\res/layout-xlarge-port/activity_main.xml #generated:26
-keep class com.kd7uiy.hamfinder.LocationDisplayFragment { <init>(...); }

# view large-land\res/layout-large-land/activity_main.xml #generated:34
# view large-port\res/layout-large-port/activity_main.xml #generated:44
# view xlarge-land\res/layout-xlarge-land/activity_main.xml #generated:35
# view xlarge-port\res/layout-xlarge-port/activity_main.xml #generated:46
-keep class com.kd7uiy.hamfinder.LogBookFragment { <init>(...); }

# view AndroidManifest.xml #generated:40
-keep class com.kd7uiy.hamfinder.MainActivity { <init>(...); }

# view AndroidManifest.xml #generated:49
-keep class com.kd7uiy.hamfinder.MainSettingsActivity { <init>(...); }

# view res/xml/pref_location.xml #generated:43
-keep class com.kd7uiy.hamfinder.MapDialogPreference { <init>(...); }

# view large-land\res/layout-large-land/activity_main.xml #generated:45
# view large-port\res/layout-large-port/activity_main.xml #generated:33
# view xlarge-land\res/layout-xlarge-land/activity_main.xml #generated:47
# view xlarge-port\res/layout-xlarge-port/activity_main.xml #generated:35
-keep class com.kd7uiy.hamfinder.dialogs.SimpleLogFragment { <init>(...); }

# view res/layout/list_item_simple_checkable.xml #generated:3
# view v11\res/layout-v11/list_item_simple_checkable.xml #generated:3
-keep class com.kd7uiy.library.CheckableLinearLayout { <init>(...); }

# view AndroidManifest.xml #generated:59
-keep class com.kd7uiy.library.ManageAddOnPurchaseActivity { <init>(...); }

# view res/layout/mistake_form.xml #generated:14
-keep class com.kd7uiy.library.MapSpinner { <init>(...); }

# view res/layout/offline_map_dialog_preference.xml #generated:6
-keep class com.kd7uiy.library.SimpleMapView { <init>(...); }

# view res/xml/pref_general.xml #generated:19
# view res/xml/pref_general.xml #generated:26
# view res/xml/pref_location.xml #generated:4
-keep class com.kd7uiy.library.SortableListPreference { <init>(...); }

# view res/layout/wise_sayings_fragment.xml #generated:2
-keep class com.kd7uiy.library.WiseSayings { <init>(...); }

# view res/layout/sort_list_array_dialog_preference.xml #generated:2
-keep class com.mobeta.android.dslv.DragSortListView { <init>(...); }

# view res/xml/pref_location.xml #generated:12
# view res/xml/pref_location.xml #generated:20
# view res/xml/pref_location.xml #generated:28
-keep class com.robobunny.SeekBarPreference { <init>(...); }

Я также попытался скомпилировать флаг ignorewarnings. Перечисленные ошибки огромны, но здесь их выборка, начиная с конца:

[2014-02-26 10:03:37 - HamFinder] Proguard returned with error code 1. See console
[2014-02-26 10:03:37 - HamFinder] Warning: com.kd7uiy.hamfinder.MainActivity: can't find superclass or interface com.kd7uiy.hamfinder.LogBookFragment$OnEditView
[2014-02-26 10:03:37 - HamFinder] Warning: com.kd7uiy.hamfinder.MapQuestReverseCoder: can't find superclass or interface com.kd7uiy.hamfinder.AbstractWebReverseGeoCoder
[2014-02-26 10:03:37 - HamFinder] Warning: com.kd7uiy.hamfinder.OfflineLocator: can't find superclass or interface com.kd7uiy.hamfinder.AbstractReverseGeoCoder
[2014-02-26 10:03:37 - HamFinder] Warning: com.google.android.gms.auth.GoogleAuthUtil: can't find referenced class com.google.android.gms.R
...Continues like this. My searching shows mainly R files missing, although I did see this:
[2014-02-26 10:03:37 - HamFinder] Warning: com.kd7uiy.hamfinder.MainActivity: can't find referenced class com.kd7uiy.hamfinder.MainActivity$2
[2014-02-26 10:03:37 - HamFinder] Warning: com.kd7uiy.hamfinder.MainActivity: can't find referenced class com.kd7uiy.hamfinder.MainActivity$2
[2014-02-26 10:03:37 - HamFinder] Warning: com.kd7uiy.hamfinder.MainActivity: can't find referenced class com.kd7uiy.hamfinder.MainActivity$3
[2014-02-26 10:03:37 - HamFinder] Warning: com.kd7uiy.hamfinder.MainActivity: can't find referenced class com.kd7uiy.hamfinder.MainActivity$3
...
[2014-02-26 10:03:37 - HamFinder] Warning: eu.inmite.android.lib.dialogs.SimpleTimePickerDialogFragment: can't find referenced class eu.inmite.android.lib.dialogs.R$layout
[2014-02-26 10:03:37 - HamFinder] Warning: eu.inmite.android.lib.dialogs.SimpleTimePickerDialogFragment: can't find referenced class eu.inmite.android.lib.dialogs.R$layout
[2014-02-26 10:03:37 - HamFinder] Warning: eu.inmite.android.lib.dialogs.SimpleTimePickerDialogFragment: can't find referenced class eu.inmite.android.lib.dialogs.R
[2014-02-26 10:03:37 - HamFinder] Warning: there were 678 unresolved references to classes or interfaces.
[2014-02-26 10:03:37 - HamFinder]          You may need to add missing library jars or update their versions.
[2014-02-26 10:03:37 - HamFinder]          If your code works fine without the missing classes, you can suppress
[2014-02-26 10:03:37 - HamFinder]          the warnings with '-dontwarn' options.
[2014-02-26 10:03:37 - HamFinder]          (http://proguard.sourceforge.net/manual/troubleshooting.html#unresolvedclass)
[2014-02-26 10:03:37 - HamFinder] Warning: there were 11 unresolved references to program class members.
[2014-02-26 10:03:37 - HamFinder]          Your input classes appear to be inconsistent.
[2014-02-26 10:03:37 - HamFinder]          You may need to recompile the code.
[2014-02-26 10:03:37 - HamFinder]          (http://proguard.sourceforge.net/manual/troubleshooting.html#unresolvedprogramclassmember)
[2014-02-26 10:03:37 - HamFinder] java.io.IOException: Please correct the above warnings first.
[2014-02-26 10:03:37 - HamFinder]   at proguard.Initializer.execute(Initializer.java:369)
[2014-02-26 10:03:37 - HamFinder]   at proguard.ProGuard.initialize(ProGuard.java:211)
[2014-02-26 10:03:37 - HamFinder]   at proguard.ProGuard.execute(ProGuard.java:86)
[2014-02-26 10:03:37 - HamFinder]   at proguard.ProGuard.main(ProGuard.java:483)

Я пробовал целый ряд вещей, чтобы заставить это работать, включая обновление proguard, обновление SDK, обновление инструментов Eclipse, загрузку новой версии Eclipse и начало с нуля, многочисленные изменения в файле proguard, none из которых, кажется, помогает в малейшей степени. Любые другие идеи?

EDIT. Вот несколько вещей, к которым я склоняюсь, как возможность.

  • Я заметил, что список предупреждений изменяется, даже если я делаю не что иное, как очистить проект и перестроить.
  • Количество ошибок, похоже, растет с количеством раз, когда я открыл eclipse и построил сборку.
  • Eclipse, похоже, чаще сбивается с ошибками кучи.

Не уверен, что это помогает, но я подумал, что я его туда брошу.

Ответ 1

Резюме. Я уверен, что ключевой проблемой была папка с исходной папкой /java вместо /src. Убедитесь, что все зависимые библиотеки имеют исходный код в папке /src, если это вообще возможно.

Как я намекнул в своем редактировании, я считаю, что это проблема с памятью. Фактически, я смог получить сборку, построенную с большим количеством проб и ошибок, и несколько настроек, внесенных в мою конфигурацию памяти eclipse. В частности, я использовал совет эту статью, а именно:

  • Увеличьте -Xmx256m до -Xmx2048m в файле eclipse.ini.
  • Добавить -XX: MaxPermSize = 256 м в файл eclipse.ini.
  • Добавить -Xms256M -Xmx512M в JVM, найденный в Window- > Preferences → Java → Установленные JREs → нажав на JRE → Изменить
  • Удаление -ignorewarnings. Это просто замаскировало проблему, я бы выяснил, что происходило намного раньше, если бы я этого не сделал. -dontwarn для известных проблем (A lib я использую необязательно использование java.awt, но не для того, что я использую...
  • Попробуйте несколько раз, чтобы заставить сборку работать, вы будете знать, что она работает, если нет ошибок в консоли.
  • Используйте Ant/Gradle, чтобы сделать

Эти шаги помогли, но, в конце концов, я смог исправить это, хотя я сделал несколько вещей сразу, любой из которых мог устранить проблему. То, что я сделал:

  • Правильно задайте порядок зависимостей, чтобы сначала скомпилировать первую библиотеку и т.д. У меня есть несколько библиотек, которые зависят от библиотек, поэтому...
  • Один из моих проектов имел код в /java вместо/src. Возможно, это вызвало некоторую путаницу, я не уверен.
  • Убедитесь, что все библиотеки нацелены на последнюю версию Android.

Теперь мои project.properties выглядят следующим образом:

proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt

# Project target.
target=android-19
android.library.reference.1=../../../workspace/android-support-v7-appcompat
android.library.reference.2=..\\..\\..\\workspace\\google-play-services_lib
android.library.reference.3=..\\..\\..\\Documents\\GitHub\\android-styled-dialogs\\library\\src\\main
android.library.reference.4=..\\..\\..\\Documents\\GitHub\\drag-sort-listview\\library
android.library.reference.5=..\\..\\..\\Documents\\GitHub\\android-maps-utils\\library

Ответ 2

Сейчас у вас

# We want to keep methods in Activity that could be used in the XML attribute onClick
-keepclassmembers class * extends android.app.Activity {
   public void *(android.view.View);
}

Ваши классы расширяют библиотеку поддержки v7 (судя по вашим проектам .properties), а не стандартную android.app.Activity, поэтому вам нужно что-то вроде:

-dontwarn android.support.v7.**
-keep public class * extends android.support.v7.app.Fragment
-keep public class * extends android.support.v4.app.Activity

или если вы хотите попытаться сохранить больше (но больший конечный apk):

-keep class android.support.v7.** { *; }

или

# We want to keep methods in Activity that could be used in the XML attribute onClick
-keepclassmembers class * extends android.support.v7.app.ActionBarActivity {
   public void *(android.view.View);
}

и то же самое для Fragment и т.д.


Обратите внимание, что ваш журнал говорит Не удается найти LogBookFragment$OnEditView, который является внутренним классом View. Перечислите их один за другим, чтобы сохранить proguard или переместить их в свой собственный файл класса.

Ответ 3

Иногда я получаю сообщения о недостающих классах при создании с помощью ProGuard в Eclipse в Windows. Причина до сих пор таинственна. ProGuard запускается как отдельный процесс script/java внутри Eclipse. Проблема возникает ложно. Я предполагаю, что скомпилированные файлы классов не удаляются в файловую систему, чтобы ProGuard их читал. Вы можете попробовать добавить паузу или просто перечислить файлы в ProGuard script android-sdk/tools/proguard/bin/proguard.bat.

Я не получал подобных отчетов о Ant или Gradle, поэтому они могут быть практическими альтернативами.

(Я разработчик ProGuard)