14

Since I updated ADT from 16 to 18 (which mandated Proguard update from 4.6 to 4.8), Proguard has been acting very weirdly (and inconsistently?).

The latest such problem is when I try to export a signed (release) APK, I receive the following errors:

Proguard returned with error code 1. See console
Warning: com.bta.LibProj2: can't find referenced class com.bta.R$string
Warning: com.bta.MyDlg1: can't find referenced class com.bta.R$string
Warning: com.bta.MyMenu: can't find referenced class com.bta.R$menu
Warning: com.bta.R: can't find referenced class com.bta.R$attr
Warning: com.bta.R: can't find referenced class com.bta.R$drawable
Warning: com.bta.R: can't find referenced class com.bta.R$menu
Warning: com.bta.R: can't find referenced class com.bta.R$string
Warning: com.bta.myapp.MyAppActivity$1: can't find referenced class com.bta.myapp.MyAppActivity
Warning: com.bta.myapp.MyAppActivity$ELicenseResponse: can't find referenced class com.bta.myapp.MyAppActivity
Warning: com.bta.myapp.MyAppActivity$MyLicenseCheckerCallback$1: can't find referenced class com.bta.myapp.MyAppActivity$MyLicenseCheckerCallback
Warning: com.bta.myapp.MyAppActivity$MyLicenseCheckerCallback$1: can't find referenced class com.bta.myapp.MyAppActivity
Warning: com.bta.myapp.R$array: can't find referenced class com.bta.myapp.R
Warning: com.bta.myapp.R$layout: can't find referenced class com.bta.myapp.R
Warning: com.bta.myapp.R$xml: can't find referenced class com.bta.myapp.R
Warning: there were 49 unresolved references to classes or interfaces.
         You may need to specify additional library jars (using '-libraryjars').
java.io.IOException: Please correct the above warnings first.
    at proguard.Initializer.execute(Initializer.java:321)
    at proguard.ProGuard.initialize(ProGuard.java:212)
    at proguard.ProGuard.execute(ProGuard.java:87)
    at proguard.ProGuard.main(ProGuard.java:493)

I did notice the recommendation to add -libraryjars in proguard.cfg, but I never needed to do this before (and I didn't change anything in my code, all I did was updating Proguard from 4.6 to 4.8). Does this suggest something wrong in my development environment configuration?

Also, I checked Proguard's Troubleshooting section for Can't find referenced class: It refers to forgetting or ignoring to specify a library via -libraryjars (which I admit), but I never specified any library and it always worked before! What changed?

My proguard.cfg file BTW starts with:

-optimizationpasses 5
-dontusemixedcaseclassnames
-dontskipnonpubliclibraryclasses
-dontpreverify
-verbose
-optimizations !code/simplification/arithmetic,!field/*,!class/merging/*

Any idea what's going on? Why did Proguard start giving me such hard time? (I coasted very smoothly with it for over a year now) Is there something fundamental I am missing in my system configuration?

BTW, I did try to add the libraries I have been using by specifying all of them in -libraryjars lines, but Proguard's behavior only got worse: It would fail without giving any of the error log that I quoted above.

Community
  • 1
  • 1
Regex Rookie
  • 10,432
  • 15
  • 54
  • 88
  • http://stackoverflow.com/questions/8540905/proguard-and-android#comment10592555_8541278 – Regex Rookie Jun 13 '12 at 04:16
  • You're answering your own question here: proguard really does need to know the location of your code, including libraries you're using. Go fix that problem. Unless you have a very deep understanding of exactly what proguard is doing, leaving out things like library jars is going to make this worse in very strange ways. (And keep in mind that Proguard's shrink step isn't that big; having a very deep understanding of exactly what proguard is doing isn't rocket science. IMHO, reading Proguard code isn't that much harder than reading proguard doc.) – James Moore Jun 15 '12 at 15:31
  • 5
    @JamesMoore You maybe right but the fact that Proguard is suggesting to use `-libraryjars` instead of simply saying "I've got no clue. Go fix that problem elsewhere" is simply horrifically irresponsible. Proguard is a great tool and its developer deserves every bit of praise -- **except for the misleading error messages.**. I highly recommend that he takes one of those UX Design classes. – Regex Rookie Jun 15 '12 at 18:56
  • It's a tool by and for programmers; you can always look at the code. Really, it's not that intimidating. Also, post your whole proguard config file, that might give us a better idea of what's going wrong. – James Moore Jun 16 '12 at 00:13
  • 5
    @JamesMoore I didn't doubt for a moment that it's a tool by programmers: http://www.uxdesignedge.com/2010/03/dont-design-like-a-programmer/ – Regex Rookie Jun 17 '12 at 11:20

3 Answers3

15

Problem solved. After much search for clues here in SO, I finally found this hint by no other than Proguard's developer himself:

-dontwarn scala.**

I'm not using anything that contains "scala" and I don't know what scala is. But that gave me the idea of placing a -dontwarn on my own application package:

-dontwarn com.bta.**

That did the trick.

For the record, the search phrase that led me to finding this hint was: proguard admob "can't find referenced class".

P.S. Proguard's suggestion You may need to specify additional library jars (using '-libraryjars') wasn't even in the right direction...

UPDATE: While -dontwarn com.bta.** allowed producing a signed APK, it crashed as soon as I tried to launch it with:

ClassNotFoundException: com.bta.myapp.MyAppActivity in loader dalvik.system.PathClassLoader[/data/app/com.bta.myapp.myapp-1.apk]. 

What a nightmare.

UPDATE 2: -dontwarn com.bta.** turned out to be way too inclusive. I changed it to:

-dontwarn com.bta.myapp.MyAppActivity.R**

And now everything runs well without incident. What a nightmare.

After wasting way too much time on debugging the very tools that are supposed to save me time, I discovered the source of the problem. It's a bug in the Android SDK tools. It is documented as have been solved in r17, but I am using the latest of today (June 18 2012) and it hasn't been solved! (see comment 24). Comment 25 also describes the workaround that allows me now to proceed with my actual development.

Bugs are fact of life in complex systems. But the fact that neither Proguard nor the build tools that feed input to Proguard could provide any helpful error message (in fact they did exactly the opposite), suggests something is broken in the "methodology" of the Android development tools recommended by Google.

Community
  • 1
  • 1
Regex Rookie
  • 10,432
  • 15
  • 54
  • 88
  • 2
    In this case, -dontwarn hides the symptoms, but it is probably not the proper solution. You should ask yourself whether the missing files should be there, check that they aren't there, and then investigate why they aren't there. Your many other questions on Stack Overflow about missing files and corrupt files suggest something else is going on. – Eric Lafortune Jun 13 '12 at 20:02
  • 7
    @Eric Lafortune I agree. It hides the symptoms of miscommunication between developers of Eclipse+SDK+ADT+Proguard before deciding on releasing the next version. The result is a total disregard to **backward compatibility** to projects that built flawlessly for years... My project didn't have *any problems* before, why should it have now? This is why I never rush to "upgrade" my tools whenever a new version is available. Wasting days on tools that are supposed to save me time is really not my idea of productivity. I know I'm not alone. Just read Christine's comments. – Regex Rookie Jun 14 '12 at 11:39
  • 1
    @EricLafortune is right, this is not the solution. All you're doing is changing warning messages. Something else changed that solved your problem. – James Moore Jun 15 '12 at 15:27
  • 5
    @James Moore Yeah but he is not suggestion any solution. "Something else" doesn't help me at all. I am still lost. I think I am going to re-install everything at the SDK 11 + Proguard 4.6 that I used to have. At least this doesn't halt development. – Regex Rookie Jun 15 '12 at 18:46
  • 1
    Well, what should help is that we're very, very confident that your solution here has absolutely nothing to do with the real solution. After reading some of the links off your proguard-hell search, though, I'm beginning to understand the problem. Many people who are clueless about proguard are posting bad advice. – James Moore Jun 16 '12 at 00:11
  • 1
    @RegexRookie: I doubt that you need to debug Proguard, you're just configuring it wrong. Try running it from the command line instead of the IDE (proguard doesn't have dialog boxes at all, so the IDE may be hiding useful information). Use -verbose and -whyareyoukeeping class_specification ; those should help track this down. I also suggest a few more readings of http://proguard.sourceforge.net/#manual/troubleshooting.html and the manual sections about keeping - you do need a good understanding of those to use Proguard. – James Moore Jun 17 '12 at 15:56
  • 1
    Try building from the command line. I've found that once in a while you'll get better error messages. (Don't normally build that way? Just run "android update project -p ." then "ant release") – James Moore Jun 17 '12 at 20:11
1

I had similar issues after the latest update of SDK and ADT, eventually requiring me to checkout my project from scratch. Try checking out a new copy of your project, see if that works.

Christine
  • 5,617
  • 4
  • 38
  • 61
  • Thanks (+1), I'll try that but I must admit that it's really frustrating to workaround a problem without understanding what caused it and what solved it. I dread every time I am forced to update my SDK+ADT because it **always** results in a loss of at least 3 productivity days. I thought that with the advance of technology, software development will become easier over time. It turns out that today's software development environment is actually worse than using punch cards in the old days. :( – Regex Rookie Jun 13 '12 at 01:08
  • 1
    Frustrating, yes. I spent about a day fixing my project. Romain Guy said at GooglIO 2009, their team doesn't use Eclipse. Now we know why :-) – Christine Jun 13 '12 at 02:04
  • 1
    Does the R file get generated? I have noticed that Eclipse doesn't give you the clear error messages any more, so sometimes an error in an xml file goes unnoticed, resulting in no R file, resulting in loads of "not found" errors. – Christine Jun 13 '12 at 03:52
  • Yes it does. Or should I say: Yes they do. There are actually 3 of them under the `/gen` dubdirectory. Corresponding to the application package itself + 2 library projects used by the application. I am at loss. Or as someone labeled it: [proguard hell](http://stackoverflow.com/q/6974231) – Regex Rookie Jun 13 '12 at 04:01
  • 1
    I'm sorry I can't help you more. I was very happy to get my project to work, I know it has something to do with the library projects, I have one of those, and I remember replacing it by a standard jar file to make it work. I don't remember what I did after that that made the library project work after all. I tried so many things.... – Christine Jun 13 '12 at 04:15
  • The root cause of the problem is actually **me**: If I really knew how each and every CPU cycle of the tools I'm using works, then I could've troubleshoot it myself. But I'm trying to take shortcuts by relying on the tools being perfect, when the reality is that there isn't any software-based tool that's perfect. I can either keep [guessing](http://stackoverflow.com/q/5784281/576267) or downgrade back to SDK 11 (ADT 16) which bars me from using AdMob. Until the developers of Eclipse, Android SDK, ADT and Proguard start speaking with each other... – Regex Rookie Jun 13 '12 at 04:23
1

First, investigate what Proguard is telling you:

Warning: com.bta.LibProj2: can't find referenced class com.bta.R$string
Warning: com.bta.MyDlg1: can't find referenced class com.bta.R$string

It can't find com.bta.R$string. Why not? Is com.bta.R$string there? Not the source code, we don't care about source at this point. Is the .class file there? If it's in the filesystem, is it actually referenced in the Proguard configuration file? Make sure you know how it's supposed to get included; what's referencing com.bta.R$string? You're probably going to be using javap to figure that out.

A better sledgehammer to use in this case isn't to turn off warnings (since they're actually warning you about something important), it's to tell Proguard to keep the com.bta classes that are missing, something like this:

-keep class com.bta.**

The recommendation to think about library jars is just a recommendation. It's apparently a common misconfiguration of proguard, so adding a note to point people in that direction is perfectly reasonable. It didn't solve your problem, but that doesn't mean it's not useful advice.

BTW, I did try to add the libraries I have been using by specifying all of them in -libraryjars lines, but Proguard's behavior only got worse: It would fail without giving any of the error log that I quoted above.

You probably need those -libraryjars entries. They don't make the problem worse. You've gone from a configuration that has N things wrong (not specifying -libraryjars) to a configuration that has N - 1 things wrong. Fix the N - 1 solution. What errors does it give, if any? If there are no errors, what happens if you turn warnings back on?

Experts only: you can in fact have a useful configuration without the -libraryjars entries, but you'll need a complete understanding of exactly what Proguard is doing with your code. And off the top of my head, I can't think of any reason other than performance for why you would want to do this.

James Moore
  • 8,636
  • 5
  • 71
  • 90
  • Proguard is telling me NOTHING. More precisely it doesn't output anything other than the error dialog box: `Failed to export application`. I tried to follow my own advice to [the guy with the WinXP problem](http://stackoverflow.com/a/11040689/576267) but that didn't help (I have Win7). When I turn off Proguard completely, Export **sometimes** issues the error messages listed in the original question and sometimes doesn't issue anything to the console, instead failing with the infamous [Conversion to Dalvik format failed with error 1](http://stackoverflow.com/a/3389640/576267). – Regex Rookie Jun 17 '12 at 12:02
  • And answering the 1st question: YES, com.bta.R$string (the .class file) is there (in the filesystem). But for some reason isn't displayed in Eclipse's Package Explorer). **Why should it be referenced in the Proguard configuration file when I never needed to do so before?** – Regex Rookie Jun 17 '12 at 12:20
  • @RegexRookie We don't have enough information to help you figure out why your old configuration was broken. I can think of reasons (code referenced through reflection; it was referenced through a wildcard and you didn't realize; you were running proguard and not using its output; that code was referenced through a code path that's been removed), but it's probably easier to figure out why it's broken now. – James Moore Jun 17 '12 at 15:47
  • I'm not the only one not having a clue: (1) http://stackoverflow.com/q/10155901/576267 (2) http://stackoverflow.com/q/11044161/576267 (3) http://stackoverflow.com/q/10723709/576267 and on and on and on... Try looking at the BIG picture. Proguard may be bug-free but if it doesn't communicate well the problems in its input... – Regex Rookie Jun 17 '12 at 16:05
  • 5
    In hindsight, the question "*Is the .class file there?*" doesn't make sense because, as I described in my original post, the problem is only with exporting signed APKs. If the `.class` file weren't there, the debug version wouldn't have worked so well. Am I mistaken? – Regex Rookie Jun 17 '12 at 19:31
  • Proguard isn't run when you compile a debug version of an Android app. – Jarett Millard Apr 21 '14 at 17:04