Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Distributing AAR privately with Gradle dependencies

I am trying to create an Android closed-source SDK package to distribute to a select number of customers.

I understand that the best way to create a distributable Android package to include source code, manifest, layout XML & other resources, etc. is to create an AAR file, and I have done this using Android Studio.

Ideally, one would then distribute the AAR via a Maven repository to allow others to use the source, along with distributing a pom.xml file which lists the dependencies.

However, I do not want to be forced to upload my AAR to a public (or even private) repository -- I simply want to have a way of simply distributing my AAR file via email or as a downloadable ZIP file.

The problem is that my library project has a number of dependencies (both from Maven and a local project) and AARs do not seem to themselves have any inbuilt support for listing (or even bundling) their dependencies and this needs to be handled externally (I think?).

This means that when including the AAR in another app, I end up getting java.lang.NoClassDefFoundError whenever I try to use any of the AAR's dependencies.

A workaround I've found (which is not ideal) is to copy the Maven dependencies into the host app's dependencies section of build.gradle. This isn't great because it's an extra step for customers to integrate the SDK, and it's not clean in terms of managing the dependency hierarchy.

This workaround also doesn't work for the project dependency I have, because that is excluded at build-time. I could probably presumably provide this dependency as source and ask my customers to add it to their project which I'm sure would work, but this just gets even messier.

So the question is: how can one create an easily-distributable AAR file that can be dropped into another app with automatic dependency resolution without needing a repository?

like image 351
Jonathan Ellis Avatar asked Sep 24 '15 16:09

Jonathan Ellis


1 Answers

The closest thing to what you are seeking is for you to distribute a Maven-style repository as a ZIP archive. This is basically what the Android Repository and Google Repository are that you get from the Android SDK. Your customers would unZIP the archive somewhere (individual workstation, common fileserver, etc.) and reference it in their module's repositories closure, then use normal compile directives. You would ship your pom.xml with pointers to the dependencies. Those dependencies that themselves are private would be part of the ZIP archive; those that are public would be pulled from JCenter or wherever.

(note: the only reason you don't need stuff in a repositories closure for the Android Repository and the Google Repository from the SDK is because the Google for Android plugin automatically adds them, more or less)

However, this will be moderately painful when you ship updates. You need to get new artifacts and pom.xml files into N copies of your original repository, where N is your number of active customers. Shipping a replacement repository is a possibility, but then that repository starts to grow linearly with the number of supported releases of your SDK. If you decide to yank support for older releases, you start breaking builds for anyone who has not yet moved up to a newer release, which may add to your support burden. Alternatively, you would need to work out the mechanics and instructions for distributing a repo "patchset" of sorts with just the new stuff, and hope that the customers install it properly.

like image 94
CommonsWare Avatar answered Oct 21 '22 03:10

CommonsWare