Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Proguard seeming to remove an entire packages that are included in the path

I use Proguard to obfuscate my code, and make it smaller. I build using Eclipse, and have for some time. I've recently had a build that works great in the debug version, which I'm trying to release. I've been trying to get this done for most of the last day, and I keep getting the following error when I try to run my code using the released build (I can produce more if it helps).

02-25 16:39:58.844: E/AndroidRuntime(27593): Caused by: java.lang.ClassNotFoundException: Didn't find class "com.kd7uiy.hamfinder.MainActivity" on path: DexPathList[[zip file "/data/app/com.kd7uiy.hamfinder-2.apk"],nativeLibraryDirectories=[/data/app-lib/com.kd7uiy.hamfinder-2, /vendor/lib, /system/lib]]

The really strange thing is, I didn't change my proguard file, at least not the first time I did this. I've since been playing with it, to see if I can get anything to get it to work, but nothing seems to do the trick. Since this build, I have added a new library to my code base, the Google Maps utility library. My last build was only a few days ago.

Trying to troubleshoot this issue, I've found that there is an entire folder that doesn't appear on the path list. I see this folder in the compiled binary classes, but they don't survive the process. If I stop using Proguard, the release version works as intended.

My code relies on 6 packages that are in my /src directory. I did not significantly alter this structure for this release, although I probably added a file or two to various folders, and might have moved a folder or two. The 6 packages are:

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

Of these, I can find no direct evidence of the following packages in my proguard mapping file, at least for this particular trial

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

Some have a few variable names referenced, but not evidence of the entire package being included. I've checked the .dex file, which does not contain the missing packages either. I should add, sometimes seemingly randomly some of the other packages will appear, but never the com.kd7uiy.hamfinder, where my MainActivity resides. Sometimes none of them appear.

Here's my project.properties file:

# 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

And my original proguard-project.txt file, which has been shown not to work.

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

I did change it to add the appropriate Google Maps required changes for Proguard as well. Neither worked.

-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

For reference here's my proguard-android.txt file, found in the correct location.

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

Here's a snapshot of my files

enter image description here

And here's my build path

enter image description here

Looking at some other files, I have seen evidence of the files in the /bin/proguard.txt file, but they just seem to disappear after that. The compiled size isn't noticeably smaller either, but that could be because I have far more non-code stuff than code, it'd be hard to detect a difference of a few java files. Here's the entire /bin/proguard.txt file.

# 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>(...); }

I've also tried compiling with the ignorewarnings flag disabled. The errors listed are huge, but here's a sampling of them, from the end:

[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)

I've tried quite a number of things to get this to work, including upgrading proguard, updating the SDK, updating the Eclipse tools, downloading a new version of Eclipse and starting from scratch, numerous changes to the proguard file, none of which seems to help in the slightest. Any other ideas?

EDIT- Here's a few things that I'm leaning towards, as a possibility.

  1. I've noticed that the warning list changes, even if I do nothing more than clean the project and re-build.
  2. The number of errors seems to grow with the number of times I've had eclipse opened and build the build.
  3. Eclipse seems to be crashing more frequently with heap errors.

Not sure if any of this helps, but I thought I'd toss it in there.

like image 246
PearsonArtPhoto Avatar asked Feb 25 '14 22:02

PearsonArtPhoto


People also ask

Does ProGuard remove unused classes?

Shrinking Options By default, ProGuard shrinks the code: it removes all unused classes and class members.

What is ProGuard obfuscation?

ProGuard is a command-line tool that reduces app size by shrinking bytecode and obfuscates the names of classes, fields and methods. It's an ideal fit for developers working with Java or Kotlin who are primarily interested in an Android optimizer.

What is Dontwarn in ProGuard?

If your code works fine without the missing classes, you can suppress the warnings with '-dontwarn' options. (


2 Answers

Right now you have

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

Your classes extend the support library v7 (judging from your project.properties) not the standard android.app.Activity, so you need something like:

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

or if you want to try to keep more (but bigger final apk):

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

or

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

and the same for Fragments etc


Note your log says Cannot find LogBookFragment$OnEditView which is an inner class View. Either list these one by one to save by proguard or move them out into their own class file.

like image 165
Blundell Avatar answered Nov 15 '22 19:11

Blundell


I occasionally receive reports about missing classes when building with ProGuard in Eclipse, in Windows. The cause is a mystery so far. ProGuard is run as a separate script/java process inside Eclipse. The problem happens spuriously. I am guessing the compiled class files aren't flushed to the file system in time for ProGuard to read them. You could try adding a pause or just list the files in the ProGuard script android-sdk/tools/proguard/bin/proguard.bat.

I have not received any similar reports about Ant or Gradle, so those may be practical alternatives.

(I am the developer of ProGuard)

like image 36
Eric Lafortune Avatar answered Nov 15 '22 17:11

Eric Lafortune