Why do I get “can’t find referenced class” errors?

When you are processing your application or a library you may get a lot of similar errors that look like this:

Warning:org.joda.time.Months: can't find referenced class org.joda.convert.FromString

And in the end a summary:

Warning: there were 52 unresolved references to classes or interfaces.

You may need to add missing library jars or update their versions. If your code works fine without the missing classes, you can suppress the warnings with '-dontwarn' options proguard.sourceforge.net/manual/troubleshooting.html#unresolvedclass

What does this mean?

The error means that ProGuard or R8 could not find a certain class that comes from a dependency.

In general ProGuard needs all the dependencies including transitive dependencies to process your code, so it complains. But your application does not really have to have all the dependencies to successfully run.

For example, your encryption library could depend on different algorithms - each in their own sublibrary - say, AES, 3DES, and Blowfish. If your application only uses 3DES, your code will perfectly run even when AES and Blowfish dependencies are not there, but ProGuard will complain.

Solution

There could be one of the two possible situations:

1. You are missing a real dependency (not very probable).
In this case, your application usually won’t work. To solve this, please specify the missing dependency using -injars option.

In the Android world this is an unlikely situation, since the build system usually collects all dependencies automatically.

2. You have an unused transitive dependency (this is what usually happens).
In this case, your application still works, but ProGuard still complains, because it needs to collect all the dependencies - both used and unused.

There are several ways to solve this, the easiest way is usually to add a -dontwarn option to your configuration. Despite the fact that suppressing warnings may feel not the cleanest way to solve the problem, it makes sense for this particular situation, since you are dealing with a transitive dependency (so not added by you) and this dependency is not used for the application.