Release a project with bundled aar libraries (aka: not releasing them in a public maven repository)

2,493 views
Skip to first unread message

Daniele Segato

unread,
Jun 5, 2013, 9:46:17 AM6/5/13
to adt...@googlegroups.com
Hi,

I need to release a project with bundled aar libraries but without publishing those libraries into maven.

Reason: we do not want to make that public, its experimental and meant for closed sharing.


I also can't release the project libraries as source code cause they are meant to be used without modifications and possibly without even looking into it.

I have a script that produce a zip file containing the Android project and the aar files with build.gradle stuffs.

I discovered the hard way that I can't include an aar as local file dependency:

dependencies {
    compile 'libs/my-local-lib.aar'
}

doesn't work.


So now I'm looking for a workaround.
Maybe building a local maven repository on the fly, set it as maven repository in build.gradle and bundle it with a zip file.


Can't find any instruction on how to publish aar artifacts for my libraries (may be this is obvious but I'm completely new to gradle).


Can you guide me in the right direction?
Regards,
Daniele

Manfred Moser

unread,
Jun 5, 2013, 12:00:23 PM6/5/13
to adt...@googlegroups.com
Install a repository manager like Sonatype Nexus in your network or on a hosted VM and deploy to it.

manfred


--
You received this message because you are subscribed to the Google Groups "adt-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email to adt-dev+u...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.
 
 

Mark Murphy

unread,
Jun 5, 2013, 12:06:56 PM6/5/13
to adt...@googlegroups.com
I sincerely hope that there is a lighter-weight solution than this, as
your solution presumes the existence of a network.
--
Mark Murphy (a Commons Guy)
http://commonsware.com | http://github.com/commonsguy
http://commonsware.com/blog | http://twitter.com/commonsguy

In questi siti web puoi chiedere o rispondere a domande relative allo
sviluppo di applicazioni Android: http://www.andglobe.com

Manfred Moser

unread,
Jun 5, 2013, 12:11:15 PM6/5/13
to adt...@googlegroups.com
No it does not. You can easily run a repo server locally on your machine. Or in the cloud if you like. This makes it much more efficient for everyone on your team since e.g. the CI server can build the aar and everybody can just declare a dependency to it and they never have to actually build it locally if they are not modifying it. 

A repo manager is the best way to deal with storing the binary dependencies and making them available for everyone on your team (and beyond if it is a public server). Android is just catching up with what everybody else has been doing for years.

manfred

Mark Murphy

unread,
Jun 5, 2013, 12:24:12 PM6/5/13
to adt...@googlegroups.com
On Wed, Jun 5, 2013 at 12:11 PM, Manfred Moser <mos...@gmail.com> wrote:
> No it does not.

I was going by what you wrote ("Install a repository manager like
Sonatype Nexus in your network").

> You can easily run a repo server locally on your machine.

Which will chew up a bunch of system RAM, which not every developer
has in abundance, given the memory costs of IDEs and emulators. My
understanding is that a repo manager is an always-running server (or
app within a Web container).

How about a solution that *doesn't* require the existence of an
always-running daemon process, or an always-on Internet connection, or
a local network for offloading that daemon process?

Manfred Moser

unread,
Jun 5, 2013, 12:27:38 PM6/5/13
to adt...@googlegroups.com
If you really insist on a cludge you can install the aar into a local repository (either a gradle/ivy one or the maven one and declare it to be used) but that way it only work for you only on your machine and not for everybody on your team so you force everyone to build everything.. 

manfred


Mark Murphy

unread,
Jun 5, 2013, 12:29:29 PM6/5/13
to adt...@googlegroups.com
On Wed, Jun 5, 2013 at 12:27 PM, Manfred Moser <mos...@gmail.com> wrote:
> If you really insist on a cludge you can install the aar into a local
> repository (either a gradle/ivy one or the maven one and declare it to be
> used) but that way it only work for you only on your machine and not for
> everybody on your team so you force everyone to build everything..

This presumes the existence of a team. Is being the member of a team a
requirement for Android development?

Siva Velusamy

unread,
Jun 5, 2013, 12:33:12 PM6/5/13
to adt...@googlegroups.com
If you use SDK Manager to download the "Google repository", you'll see
that it contains the play services distributed as an aar in a maven
repository format (extras/google/m2repository). This repository is
added by default by the gradle plugin. I'm sure you can do something
similar, except users would have to explicitly add a local repository.

Manfred Moser

unread,
Jun 5, 2013, 12:36:25 PM6/5/13
to adt...@googlegroups.com
On Wed, Jun 5, 2013 at 9:29 AM, Mark Murphy <mmu...@commonsware.com> wrote:
On Wed, Jun 5, 2013 at 12:27 PM, Manfred Moser <mos...@gmail.com> wrote:
> If you really insist on a cludge you can install the aar into a local
> repository (either a gradle/ivy one or the maven one and declare it to be
> used) but that way it only work for you only on your machine and not for
> everybody on your team so you force everyone to build everything..

This presumes the existence of a team. Is being the member of a team a
requirement for Android development?

It does not but I sure hope you are not alone.. and if you are you should still be using a decent infrastructure or at least laptop that can easily manage things like running a lightweight server.. it will make it easier... 

manfred

Daniele Segato

unread,
Jun 5, 2013, 1:35:12 PM6/5/13
to adt...@googlegroups.com

On Wednesday, June 5, 2013 6:00:23 PM UTC+2, Manfred Moser wrote:
Install a repository manager like Sonatype Nexus in your network or on a hosted VM and deploy to it.


No applicable for me.

I need to release a Zip file with some source and bundled libraries (in binary format) without making them public.
 

Xavier Ducrohet

unread,
Jun 5, 2013, 1:34:16 PM6/5/13
to adt...@googlegroups.com
local aar are not yet supported. I want to add support for it (it's fairly trivial) but I want to figure out the impact of it.

Having a local aar means that this aar cannot have any other dependencies besides local jar. This is because, unlike jars, the order of the aar dependency is important.

Let's imagine if you have lib1 and lib2 with a project dependency that is app -> lib1 -> lib2.

Publishing lib1 and lib2 to a repo keeps the lib1->lib2 dependency. Adding lib1 as a dependency to app will ensure the order is kept.

Now going the local way, you would have to generate both aar and manually add both as dependencies to app. At this point there's nothing to guarantee that lib1 and lib2 are added in the right order.

It almost sound simple to ensure lib1 and lib2 are properly ordered. But if you have more dependencies, in a complex graph (ie not just lib1->lib2->lib3...->lib(n)...) computing the order is non trivial.

Local dependencies are possible because sometimes developers have to use them. But it can make things very very tricky, and I want to see how we can mitigate this.

Currently your best bet, if you don't have a network) is to actually generate a local repository with all the dependencies and to ship it as a zip to the developers would need them. This way they get a configured repository with all the dependencies setup (ie they don't have to publish them manually to their local repo).

It's ugly (I can hear Manfred groan already ;)), but if you really don't want to use a network, that's kinda the best solution IMO.


On Wed, Jun 5, 2013 at 6:46 AM, Daniele Segato <daniele...@gmail.com> wrote:

--
You received this message because you are subscribed to the Google Groups "adt-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email to adt-dev+u...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.
 
 



--
Xavier Ducrohet
Android SDK Tech Lead
Google Inc.
http://developer.android.com | http://tools.android.com

Please do not send me questions directly. Thanks!

Xavier Ducrohet

unread,
Jun 5, 2013, 1:38:24 PM6/5/13
to adt...@googlegroups.com
If you are alone and have several reusable libraries that you want to use in different project, you can just publish them to your local maven repo (~/.mvn). It's super easy and makes them accessible to any other project.

You can publish snapshot there, or full version. I don't see the need for a server, though you'll have to manually clean snapshot uploads manually.

That said if the reusable libraries have no other dependencies, using local files is a possibility. But I trust you Mark to understand what's your doing. For the average beginner that's a bit more complicated (though he/she would probably have simpler requirements to start with).


--
You received this message because you are subscribed to the Google Groups "adt-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email to adt-dev+u...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.


Manfred Moser

unread,
Jun 5, 2013, 1:44:04 PM6/5/13
to adt...@googlegroups.com
On Wed, Jun 5, 2013 at 10:34 AM, Xavier Ducrohet <x...@android.com> wrote:
local aar are not yet supported. I want to add support for it (it's fairly trivial) but I want to figure out the impact of it.

Having a local aar means that this aar cannot have any other dependencies besides local jar. This is because, unlike jars, the order of the aar dependency is important.

Let's imagine if you have lib1 and lib2 with a project dependency that is app -> lib1 -> lib2.

Publishing lib1 and lib2 to a repo keeps the lib1->lib2 dependency. Adding lib1 as a dependency to app will ensure the order is kept.

Now going the local way, you would have to generate both aar and manually add both as dependencies to app. At this point there's nothing to guarantee that lib1 and lib2 are added in the right order.

It almost sound simple to ensure lib1 and lib2 are properly ordered. But if you have more dependencies, in a complex graph (ie not just lib1->lib2->lib3...->lib(n)...) computing the order is non trivial.


I am not sure I understand the problem. If you go the local way and just declare lib1 as dependency and use a local repository where the lib1 and lib2 are installed and the lib1 aar is deployed with a pom that declares the dependency to lib2 just like it would in a remote repository everything should be fine.

On a larger scale I would however like to know why order is important anyway ... is it just important for the manifest merging or for something else? 

manfred

Daniele Segato

unread,
Jun 5, 2013, 1:52:27 PM6/5/13
to adt...@googlegroups.com
On Wednesday, June 5, 2013 7:34:16 PM UTC+2, Xavier Ducrohet wrote:
local aar are not yet supported. I want to add support for it (it's fairly trivial) but I want to figure out the impact of it.


Yep, read that on G+ :)
 
Having a local aar means that this aar cannot have any other dependencies besides local jar. This is because, unlike jars, the order of the aar dependency is important.

Let's imagine if you have lib1 and lib2 with a project dependency that is app -> lib1 -> lib2.

Publishing lib1 and lib2 to a repo keeps the lib1->lib2 dependency. Adding lib1 as a dependency to app will ensure the order is kept.

Now going the local way, you would have to generate both aar and manually add both as dependencies to app. At this point there's nothing to guarantee that lib1 and lib2 are added in the right order.

It almost sound simple to ensure lib1 and lib2 are properly ordered. But if you have more dependencies, in a complex graph (ie not just lib1->lib2->lib3...->lib(n)...) computing the order is non trivial.

Local dependencies are possible because sometimes developers have to use them. But it can make things very very tricky, and I want to see how we can mitigate this.

Thank you for this.
Now I better understand your reasons to keep this out.

 
Currently your best bet, if you don't have a network) is to actually generate a local repository with all the dependencies and to ship it as a zip to the developers would need them. This way they get a configured repository with all the dependencies setup (ie they don't have to publish them manually to their local repo).

It's ugly (I can hear Manfred groan already ;)), but if you really don't want to use a network, that's kinda the best solution IMO.


I figured this out.

and I'm trying to do so for a couple of hour now, without success. (partly cause I've no experience with gradle / groovy)


This what I have (root build.properties):

  1. subprojects { subProject ->
  2.         apply plugin: 'maven-publish'
  3.  
  4.         // according to
  5.         // this is a workaround to make it create bundleRelease object that I export below
  6.         // but it fail to solve it apparently.
  7.         subProject.android.libraryVariants
  8.  
  9.         publishing {
  10.                 publications {
  11.                         maven(MavenPublication) {
  12.                                 artifact bundleRelease
  13.                         }
  14.                 }
  15.                 repositories {
  16.                         maven {
  17.                                 url "file:///tmp/myRepo"
  18.                         }
  19.                 }
  20.         }
  21. }


And a random subproject library:

  1. repositories {
  2.     mavenCentral()
  3. }
  4.  
  5. buildscript {
  6.     repositories {
  7.         mavenCentral()
  8.     }
  9.     dependencies {
  10.         classpath 'com.android.tools.build:gradle:0.4'
  11.     }
  12. }
  13.  
  14. apply plugin: 'android-library'
  15.  
  16. dependencies {
  17. //    compile fileTree(dir: 'libs', include: '*.jar')
  18.         compile 'com.android.support:support-v4:13.0.0'
  19.         compile 'com.fasterxml.jackson.core:jackson-core:2.1.4'
  20.         compile 'com.fasterxml.jackson.core:jackson-databind:2.1.4'
  21.         compile 'com.fasterxml.jackson.core:jackson-annotations:2.1.4'
  22.     compile project(':libs:facebook-android-sdk:facebook')
  23.     compile project(':libs:another_lib')
  24. }
  25.  
  26. android {
  27.     compileSdkVersion 17
  28.     buildToolsVersion "17.0.0"
  29.  
  30.     sourceSets {
  31.         main {
  32.             manifest.srcFile 'AndroidManifest.xml'
  33.             java.srcDirs = ['src']
  34.             resources.srcDirs = ['src']
  35.             aidl.srcDirs = ['src']
  36.             renderscript.srcDirs = ['src']
  37.             res.srcDirs = ['res']
  38.             assets.srcDirs = ['assets']
  39.         }
  40.  
  41.         instrumentTest.setRoot('tests')
  42.     }
  43. }


I get this error:

 ./gradlew build publish
...
Caused by: org.gradle.api.InvalidUserDataException: Cannot create a Publication named 'bundleRelease' because this container does not support creating elements by name alone. Please specify which subtype of Publication to create. Known subtypes are: MavenPublication
 
* What went wrong:
A problem occurred configuring project ':engage_lib'.
> Cannot create a Publication named 'bundleRelease' because this container does not support creating elements by name alone. Please specify which subtype of Publication to create. Known subtypes are: MavenPublication



So I'm stuck there, I don't know how to create this local repository.
Its probably me being ignorant on how to properly configure gradle :) but I coudln't find documentation.

Is anyone willing to help?
I have a very close deadline, but even if I fail it I'll need it.

Thank you very much in advance,

Daniele

Manfred Moser

unread,
Jun 5, 2013, 1:56:06 PM6/5/13
to adt...@googlegroups.com
use the uploadarchives command .. more details are on the gradle docs




Daniele

--

Daniele Segato

unread,
Jun 5, 2013, 2:01:46 PM6/5/13
to adt...@googlegroups.com
On Wednesday, June 5, 2013 7:56:06 PM UTC+2, Manfred Moser wrote:
use the uploadarchives command .. more details are on the gradle docs



thank you Manfred!

I used this before but without subprojects { ... } and it wasn't working.

Now I have to set up group, artifact, versions for every project and then I'm done!

Thank you again...

I hope this discussion keep going about local aar inclusion cause it was really interesting.

Regards,
Daniele

Mark Murphy

unread,
Jun 5, 2013, 2:08:00 PM6/5/13
to adt...@googlegroups.com
On Wed, Jun 5, 2013 at 1:38 PM, Xavier Ducrohet <x...@android.com> wrote:
> If you are alone and have several reusable libraries that you want to use in
> different project, you can just publish them to your local maven repo
> (~/.mvn). It's super easy and makes them accessible to any other project.

That seems manageable.

> You can publish snapshot there, or full version. I don't see the need for a
> server, though you'll have to manually clean snapshot uploads manually.

I am sure that those statements mean something to somebody. They might
even make sense to me someday. The fact that those statements will
need to make sense to hundreds of thousands of Android developers --
many of whose Java experience is limited -- is a source of some worry.

> That said if the reusable libraries have no other dependencies, using local
> files is a possibility. But I trust you Mark to understand what's your
> doing. For the average beginner that's a bit more complicated (though he/she
> would probably have simpler requirements to start with).

Whether the "local files" are bare .aar files, or are in a special
directory with special XML metadata (Maven repo directory), should be
within reach. A dedicated developer-managed server is not, IMHO,
though teams that wish to opt into one are certainly welcome to do so.

Xavier Ducrohet

unread,
Jun 5, 2013, 2:21:49 PM6/5/13
to adt...@googlegroups.com
I meant local as in doing dependencies directly on a local .aar file, not on an artifact located in your local repo.

The order is important for manifest merging, but more importantly for resource merging (since each library is overlayed by its users).


--
You received this message because you are subscribed to the Google Groups "adt-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email to adt-dev+u...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.
 
 

Xavier Ducrohet

unread,
Jun 5, 2013, 2:25:25 PM6/5/13
to adt...@googlegroups.com
you can also look at the samples at the bottom of http://tools.android.com/tech-docs/new-build-system

There's a sample called "repo" that has a bunch of libraries and an app module and they all depend on each other through a local maven repo.


Daniele

--
You received this message because you are subscribed to the Google Groups "adt-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email to adt-dev+u...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.
 
 

Daniele Segato

unread,
Jun 6, 2013, 3:28:34 AM6/6/13
to adt...@googlegroups.com
Thanks Xavier,

I already configured it in the same way! But that archive with sample will be very useful!
I didn't saw it yesterday, it would have saved me lot of time.

thanks again.

I'm now looking on how to include the javadoc with the aar artifact.
but I can't find any documentation about this.
Even those example doesn't have one.

Again, its probably my fault not knowing gradle ;)


Cheers,
Daniele

Xavier Ducrohet

unread,
Jun 6, 2013, 11:51:14 AM6/6/13
to adt...@googlegroups.com
Yeah we don't yet package the source or javadoc in there. I need to add this.

Manfred Moser

unread,
Jun 6, 2013, 1:17:03 PM6/6/13
to adt...@googlegroups.com
The default convention for javadoc as well as source for any other artifact in a repository is not to have it in the primary artifact (e.g. the jar) but have a separate one with the respective classifier.

I would suggest to follow that approach since it will automatically work with all the tools that have support for that including Android Studio/Intellij, Eclipse, Gradle, Maven, sbt, Leiningen, Ant/ivy and so on..

E.g. see http://search.maven.org/#artifactdetails|junit|junit|4.11|jar where there is a junit jar as well as the -sources and -javadoc jar files.

Lets not reinvent the wheel and do something different.

manfred

Xavier Ducrohet

unread,
Jun 6, 2013, 1:44:29 PM6/6/13
to adt...@googlegroups.com
the current convention is (maybe) driven by the fact that the Jar file is not just used by the toolchain but at runtime as well. This is not the case for aar files.

If we want to support local aar (not in a repository) then having the source/doc inside just makes more sense.

Manfred Moser

unread,
Jun 6, 2013, 1:56:04 PM6/6/13
to adt...@googlegroups.com
On Thu, Jun 6, 2013 at 10:44 AM, Xavier Ducrohet <x...@android.com> wrote:
the current convention is (maybe) driven by the fact that the Jar file is not just used by the toolchain but at runtime as well. This is not the case for aar files.

If we want to support local aar (not in a repository) then having the source/doc inside just makes more sense.


I dont see how that is related to where the aar file comes from. At a minimum I would suggest to make the separate components when deployed to a repository so you are not breaking all other tools. And even for local aar files.. nothing stops you from using the same naming convention as in a repository and just have three files. It would work just fine.. 

Daniele Segato

unread,
Jun 6, 2013, 3:17:22 PM6/6/13
to adt...@googlegroups.com
Hum,

I'm not convinced.

Jars, even if imported locally, can have their javadoc / sources attached by the tool (Eclipse / IntelliJ) etc...

The reason to have them in separate classifier is that I can release an artifact binary + javadoc in public and keep the sources classifier private if I want to only use it internally in my company.

I'd go with the separate artifact classifiers for both of them.

of course this is my opinion, but it would be more standard to what people are used to :)


Is this also the reason Intellij is not showing javadoc / sources for the support library?

Regards,
Daniele

Daniel Stonier

unread,
Jun 11, 2013, 4:58:10 AM6/11/13
to adt...@googlegroups.com
Something like this worked well for me, except that it didn't add transitive dependencies to the maven pom's. Did anyone else run into this problem as well?

Daniel.

Fabian Kajzar

unread,
Aug 4, 2013, 10:48:39 AM8/4/13
to adt...@googlegroups.com
Can you replace
artifact bundleRelease

with

artifact '/relative/reference/to/file'
Reply all
Reply to author
Forward
0 new messages