15

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.

PearsonArtPhoto
  • 38,970
  • 17
  • 111
  • 142
  • I dont see you keeping this in your proguard cfg `[2014-02-26 10:03:37 - HamFinder] Warning: com.kd7uiy.hamfinder.MapQuestReverseCoder: can't find superclass or interface com.kd7uiy.hamfinder.AbstractWebReverseGeoCoder` – blindstuff Feb 27 '14 at 01:04
  • `AbstractWebReverseGeoCoder` exists in the , I'm not sure why proguard couldn't find that. I don't know why it should be in proguard config, I don't need to name every class there, do I? Besides, I've compiled with that file there before... – PearsonArtPhoto Feb 27 '14 at 01:47
  • Name that class in the proguard cfg as a test, if the log error changes, that might be it. – blindstuff Feb 27 '14 at 03:53
  • How am I supposed to name it? `-keep class com.kd7uiy.hamfinder.AbstractWebReverseGeoCoder`? – PearsonArtPhoto Feb 27 '14 at 14:29
  • Yes. I'm almost certain that will not solved the whole issue. Since its abstract, the implementation of that will most likely need to be named. But if it changes the error message for the missing class, its a start. Proguard requires you to keep all clases that are accessed by name. I know this sounds wierd, but a good understandable example is when using GSON. Any class that GSON will touch must remain un-obfuscated so GSON can find it by its name. I'm thinking this is along the same lines. – blindstuff Feb 27 '14 at 14:46
  • As I mentioned, I've done a lot of releases with that function, and nothing has really changed. I did change the way that the abstract function worked this build, but the interfaces are all the same. Still, I can give it a shot... Will do so when I'm next near my code. – PearsonArtPhoto Feb 27 '14 at 15:06
  • Go here `${sdk.dir}/tools/proguard/proguard-android.txt` check that you have that file AND show us what it contains – Blundell Feb 27 '14 at 22:14
  • It is there, and I've added it. – PearsonArtPhoto Feb 27 '14 at 22:17
  • check this answer: http://stackoverflow.com/a/33392069/277345 – Andrey Nikishaev Oct 28 '15 at 13:19

3 Answers3

4

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.

Blundell
  • 75,855
  • 30
  • 208
  • 233
  • ActionBarActivity extends Activity eventually, so the activity should still be in place... Still, the Fragment portion is of use, and would have saved me a crash or two, so... – PearsonArtPhoto Feb 27 '14 at 22:28
  • I've now tried all of this, and it doesn't seem to fix the problem. Thanks anyhow! – PearsonArtPhoto Feb 27 '14 at 22:40
  • It looks like it can't find any of your inner classes (`SomeClass$InnerClassName` means inner class). Needs a combination of listing them + `-keepattributes InnerClasses` – Blundell Feb 27 '14 at 22:49
  • I don't know how long that error has been showing up, but I do know that I have done several releases without specifying inner classes. Besides, most of the files listed as missing are R files, which Proguard should be ignoring already, per the Android Proguard file. – PearsonArtPhoto Feb 27 '14 at 23:01
  • /bin/proguard.txt has everything that looks like it's required, I could post that as well. I'm pretty sure that's the file that's actually used... – PearsonArtPhoto Feb 27 '14 at 23:03
  • You can always check your `seeds.txt` to see what files are being kept – Blundell Feb 27 '14 at 23:04
  • That makes the job a lot easier to figure out what's in there. Didn't realize that... – PearsonArtPhoto Feb 27 '14 at 23:06
2

Summary: I'm pretty sure the key problem was the folder with the /java source folder instead of /src. Make sure any dependent libraries have their source code in a /src folder, if at all possible.

As I hinted in my edit, I believe this is a memory problem. In fact, I was able to get the build built with a lot of trial and error, and a few adjustments made to my eclipse memory configuration. Specifically, I used the advice from this article, namely:

  1. Increase the -Xmx256m to -Xmx2048m in the eclipse.ini file.
  2. Add -XX:MaxPermSize=256m to the eclipse.ini file.
  3. Add -Xms256M -Xmx512M to the JVM, found at Window-> Preferences -> Java -> Installed JREs -> clicking on JRE -> Edit
  4. Removing -ignorewarnings. That just masked the problem, I would have figured out what was going on a lot earlier if I hadn't done that. -dontwarn for the known issues (A lib I use optionally uses java.awt, but not for the stuff I use...
  5. Try multiple times to get the build to work, you'll know it works if there are no console errors.
  6. Use Ant/ Gradle to make

These steps helped, but in the end, I was able to fix it, although I did several things all at once, any of which could have fixed the problem. The things I did:

  1. Set the order of dependencies correctly, so that the first library included is compiled first, and so on. I have a few libraries that depend on libraries, so...
  2. One of my projects had the code in /java instead of /src. This might have caused some confusion, I'm not sure.
  3. Making sure all libraries target the latest Android build.

My project.properties looks like this now:

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
PearsonArtPhoto
  • 38,970
  • 17
  • 111
  • 142
  • 1
    If this is a memory problem, I wonder if [building from the command line using ant](http://developer.android.com/tools/building/building-cmdline.html) can be a quick fix for you. From my few experiences, it is usually easy to adjust a project that already run from Eclipse to also build from the command line (mostly involve running `android update project` for all the projects, adding the keystore information to the main project's `ant.properties` file, and then running `ant release`). Good luck! – Joe Feb 28 '14 at 19:58
  • That's exactly my thought, I've been itching to try that out as a matter of fact. I've also thought of moving to Android Studio, which would also likely accomplish the same thing... – PearsonArtPhoto Feb 28 '14 at 20:02
2

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)

Eric Lafortune
  • 45,150
  • 8
  • 114
  • 106
  • Where would I add the pause in proguard.bat? – PearsonArtPhoto Mar 01 '14 at 11:34
  • By the way, I'm more than willing to help you troubleshoot this problem, if you have anything you want me to try, just let me know. – PearsonArtPhoto Mar 01 '14 at 14:06
  • I tried putting in a pause statement, and it didn't work. In fact, it compiled, but was more likely to have problems after I installed it, so I went back to the previous iteration. – PearsonArtPhoto Mar 03 '14 at 21:21
  • If you let the script log the contents of the temporary input jar for ProGuard, right before actually invoking ProGuard, are all classes present? The name of the temporary input jar is one of the arguments of the script (it should also be listed in ProGuard's log, but it's too late then). If the jar is truncated or incomplete, there's a syncing problem. If the classes are present, does disabling all processing in ProGuard help (-dontshrink -dontoptimize -dontobfuscate)? – Eric Lafortune Mar 04 '14 at 01:29
  • I managed to fix it (See my answer), and while I'm still struggling to figure out why, I suspect it was making sure the order of the libraries was correct, such that if one library depended on another, that library was first. I'll do some experiments tomorrow and see if I can reproduce it, but that might be the clue. – PearsonArtPhoto Mar 04 '14 at 03:44
  • Okay, I'm 90% certain that the cause is related to a library that uses a `/java` folder instead of a `/src` folder. Not sure if that helps, but... – PearsonArtPhoto Mar 07 '14 at 02:52
  • Thanks for your experiments. I'll keep this in mind. It's still odd that the problem is non-deterministic. If there is a timing issue or a race condition in Eclipse, completely unrelated changes may appear to solve the problem. Anyhow, if your changes have solved the problem for you, that's a success. – Eric Lafortune Mar 08 '14 at 00:17