I have an Android aar library I am using with an Android application. It is working correctly with the aar library included directly in the Android project. I would like to move this library to my internal Nexus maven repository, so that other developers can use the library too.
How do I upload the aar to Nexus (the Maven repository)? There is no apparent option to do so in the web interface:
For Android, we normally have two build.gradle files the one at the top level folder, and another one in the specific module:
app/
---build.gradle
---module/
------build.gradle
In the app/build.gradle file of the clients of this library you will have to add:
repositories {
jcenter()
maven {
url "http://localhost:8081/repository/test-maven-repo/"
}
}
For you library app/module/build.gradle file:
apply plugin: 'maven'
uploadArchives {
repositories {
mavenDeployer {
repository(url: "http://localhost:8081/repository/test-maven-repo/") {
authentication(userName: "admin", password: "admin123")
pom.groupId = "com.example.test"
pom.artifactId = "myexample.test"
pom.version = '1.0.0'
}
}
}
}
And you might want to run it just with:
./gradlew upload
Link to official documentation:
Maven Publish Plugin.
I used gradle's maven plugin to upload to Nexus by modifying the Android build.gradle file.
apply plugin: 'maven'
dependencies {
deployerJars "org.apache.maven.wagon:wagon-http:2.2"
}
uploadArchives {
repositories.mavenDeployer {
configuration = configurations.deployerJars
repository(url: "https://my.example.com/content/repositories/com.example/") {
authentication(userName: "exampleUser", password: "examplePassword")
pom.groupId = "com.example"
pom.artifactId = "myexample"
pom.version = '1.0.0'
}
}
}
To upload: gradlew upload, using the gradlew script that is provided by the Android Studio project.
You can also move the authentication parameters into a file that is not version controlled.
Use maven deploy plugin. Example command:
mvn deploy
This assumes you have correctly configured your pom.xml with distributonManagement section, telling all it needs to know about your Nexus repo
If you're that kind of people who dislike changing your pom.xml, or worse if your code doesn't even have pom.xml but you still want to upload to Nexus anyway, then you can still do it using
mvn deploy:deploy-file -Durl=http://mycompany/nexus/repo/blah -Dfile=/path/to/my/foo.aar -Dpackaging=aar -DgroupId=com.mycompany -DartifactId=foo -Dversion=1.2.3
Refer to maven deploy plugin doc for more info: https://maven.apache.org/plugins/maven-deploy-plugin/
If you are building your project using Gradle, here there is a good tutorial to push your artifacts to Nexus:
https://medium.com/#scottyab/how-to-publish-your-open-source-library-to-maven-central-5178d9579c5#.acynm6j49
Basically, it adds a new Gradle task (uploadArchives) to push your artifacts. So doing something like:
>gradle clean build uploadArchives
You can upload it with Maven or Gradle or manually.
For the manual upload you can just type the package value in the input to be 'aar' and upload as you desire.
It doesn't make any sense that why nexus package have nothing for #aar file but if you try to upload it as a jar then it will not block you and everything is work as it is..
Related
I am working on an Android SDK made of multiple library modules and a test app module:
mySDK
|-test-app
|-lib-core
|-lib-ui
|-...
I would like to publish it on a Maven repository, with all library modules embedded (but not the test-app).
I know how to publish a single library module using Maven Publish Plugin but can't figure out how to make a Maven publication containing multiple library modules.
How would you do that ?
Just upload each module as a standalone module.
It is not mandatory to upload all the modules at the same time, the dependencies are just described in the pom file.
It can be useful putting a base script in a single gradle file with some common settings and properties (you can read them from a gradle.properties file), something like:
rootFolder/maven_push.gradle:
apply plugin: 'maven'
//....
pom.artifactId = POM_ARTIFACT_ID
pom.project {
name POM_NAME
packaging POM_PACKAGING
description POM_DESCRIPTION
url POM_URL
//...
}
//...
and then in each module/build.gradle file add:
apply from: '../maven_push.gradle'
Each module is a library by itself, so configure each one of them (besides the app) to be packaged as AAR files and deployed to the desired repo. If you are going to use the Maven publish plugin, just apply the steps to each module(to the module's build.gradle files). A good practice is to centralize the groupId and version values, perhaps in the gradle.properties file, or in the main gradle file. Same procedure applies to other plugins, like the android-gradle-maven plugin.
I am trying to integrate an Android archive (aar) from local Maven to Android studio in my sample project.
I am getting the following build error in Android studio:
A problem occurred evaluating project :app Could not find property HOME on org.gradle.api.internal.artifacts.repositories.DefaultMavenArtifactRepository_Decorated#181db40.
If you are using local maven to work with android studio you need to do this means that to add a reference to an .aar package it would have to ideally be stored in the central maven repository.
A simple and extremely straightforward option is to create a local maven repository on your dev machine, and install your library in there. Then reference it from your gradle build. And doing it is surprisingly simple!.
Since you're developing for android, I assume you already installed the latest JDK and set the JAVA_HOME environment variable, but if you didn't - now is the time.
Then you'd want to install Maven. You can download it here: http://maven.apache.org/download.cgi
Set the MAVEN_HOME environment variable to the path where you extracted maven, and add the maven's bin folder to the PATH environment variable.
To test that maven is working fine, open a new console window and run the following:
mvn -version
If everything is fine, it's time to add your library to the maven repository. In the command prompt run the following:
mvn install:install-file -Dfile=d:\mylibrary-{version}.aar -DgroupId=com.example -DartifactId=mylibrary -Dversion={version} -Dpackaging=aar
Don't forget to replace the proper path to your library, setting your groupId, artifactId and version number.
Finally, edit your build.gradle to start looking at the local maven repository. For example, if you want to use both maven central and your local repo you can add both of them to the repositories configuration.
Here's an example of a very basic build.gradle for an android app using the library we registered above:
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath 'com.android.tools.build:gradle:0.4.2'
}
}
apply plugin: 'android'
repositories {
mavenCentral()
mavenLocal()
}
dependencies {
compile('com.example:mylibrary:0.2')
}
android {
compileSdkVersion 17
buildToolsVersion '17.0.0'
}
Finally, run the build command to build your app:
gradle clean build.
The main problem is to get the resulting .aar file in the maven publication profile. To do that we'll run a call to android.libraryVariants, which will initialise this object, and create all the subtasks required for the build, including "bundleRelease" which is creating the .aar file.
Here is what my build.gradle file looks like:
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath 'com.android.tools.build:gradle:0.4.2'
}
}
apply plugin: 'android-library'
apply plugin: 'maven-publish'
version '0.2'
group 'com.example'
android {
compileSdkVersion 17
buildToolsVersion '17.0.0'
defaultConfig {
versionCode 2
versionName '0.2'
}
}
android.libraryVariants
publishing {
publications {
maven(MavenPublication) {
artifact bundleRelease
}
}
}
If you want to change the artifactId to something custom, you can change the project name in settings.gradle by adding this line:
rootProject.name = 'mylibrary'
That's it. Now open a command prompt in your project's folder and run the following to build and publish your library to the local maven repository:
gradle clean build publishToMavenLocal
A couple basic articles that I used to get this to work:
How to install maven on windows.
Adding local .aar to gradle build
I'm trying to publish an Android library as a Maven artifact on a Bitbucket repository, starting from this article that was linked in an Android Weekly newsletter issue some time ago. The article describes how to perform publication and how to link the published artifact from another Android project. However, I have not even managed to make the publishing part to correctly work.
Currently, this is the relevant content of the build.gradle file belonging to the library project:
apply plugin: 'maven'
allprojects {
repositories {
jcenter()
maven {
url "https://raw.github.com/synergian/wagon-git/releases"
}
}
}
configurations {
deployerJar
}
dependencies {
deployerJar 'ar.com.synergian:wagon-git:0.2.5'
}
The relevant parts of the build.gradle file of the library module in the project are as follows:
apply plugin: 'maven'
uploadArchives {
configuration = rootProject.configurations.archives
repositories {
configuration = rootProject.configurations.deployerJar
mavenDeployer {
pom.groupId = 'com.example'
pom.artifactId = 'example-library'
pom.version = '1.0.0'
repository(url: "${bitbucketUrl}") {
authentication(userName: bitbucketUsername, password: bitbucketPassword)
}
}
}
}
where bitbucketUrl, bitbucketUsername and bitbucketPassword are included in the gradle.properties file at the root of the project.
So, what's the problem? When I run the uploadArchives task from Android Studio, Gradle shows that the operation has been performed successfully. But nothing appears on the Bitbucket repository.
Nothing is also written about the structure of that repository, except on Wagon Git's website (calling it documentation seems a little bit of a stretch to me) where, given repository URL of the form
git:releases://git#github.com:synergian/wagon-git.git
it is said that releases represent a branch of the repository. I obliged that part about the structure, even tried to add a repository directory (to mimick the local Maven repository on my machine) but with no luck, and, above all, no clue.
An even more severe issue is that, while I was experimentating with different configurations, I noticed I had the repository URL wrong; however, never, ever, during execution, Gradle noticed the error, and warned or informed me with a suitable message. This lead me to suspect that it wasn't even preparing the artifact to upload, nor trying to connect to Bitbucket, but I was not able to find any pointer as to understand why.
Finally, an even more strange thing happens: when I comment out the line:
configuration = rootProject.configurations.deployerJar
in the module build.gradle file and I run the uploadArchives task, Gradle stops with an error saying that it is unable to find a proper wagon to manage the git protocol, which is expected; however, in the process, the Maven artifact appears in the local repository on my machine. So, by making the publishing process crash, at least I am able to work locally with my library from other projects depending on it, through Gradle management of Maven-like dependencies.
What am I doing wrong?
Fails silently, turn on --info. Probably the biggest hurdle in debugging the problem. For some reason, the folks who wrote the wagon-git deployer decided to write out error messages at the info level. So gradle fails silently without showing you any error messages. This is one of the messages I got with --info turned on:
[INFO] [git] fatal: 'git#bitbucket.org/foragerr/mvn-deploy-test.git' does not appear to be a git repository
This is apparently a fatal error, but as far as gradle is concerned, everything is fine and dandy. Once you start reading these error messages, we can make real progress!
git url: The git URL as outlined here, starts with git:. The wagon-git deployer is activated when the url starts with git:. It is possible to use a https: url, but maven plugin will use an internal deployer rather than wagon-git. To explicitly use wagon-git, the url has to start with git:
repository(url: "git:releases://git#bitbucket.org:foragerr/mvn-bitbucket-deploy-test.git")
where
releases is branch
foragerr is bitbucket username
mvn-bitbucket-deploy-test is bitbucket repo
Authentication: wagon-git uses SSH to connect to bitbucket. You need to setup both git on the local end and bitbucket repo on the remote end to use SSH.
Setting up SSH for git (I recommend not using a passcode, less secure, but convenient for automated deployments)
All Set! deploy to your bitbucket repo using gradle uploadArchives. See example repo here.
Sample build.gradle:
group 'net.foragerr.test'
version '1.2-SNAPSHOT'
apply plugin: 'java'
apply plugin: 'maven'
sourceCompatibility = 1.5
repositories {
mavenCentral()
maven {
url "https://raw.github.com/synergian/wagon-git/releases"
}
}
configurations {
deployerJar
}
dependencies {
testCompile group: 'junit', name: 'junit', version: '4.11'
deployerJar "ar.com.synergian:wagon-git:0.2.3"
}
uploadArchives {
repositories.mavenDeployer {
configuration = configurations.deployerJar;
repository(url: "git:releases://git#bitbucket.org:foragerr/mvn-bitbucket-deploy-test.git")
}
}
Here is all you need to do, you even need to use the git protocol (this examples show how to use the HTTPS instead):
1) create an app password for your app in Bitbucket
https://bitbucket.org/account/user/YOUR_USERNAME_HERE/app-passwords
2) inside build.gradle:
apply plugin: 'java'
apply plugin: 'maven'
// artifact --> rootProject.name at settings.gradle <--
// DOWN HERE just add your artifact INFO
group = 'br.com.fora.temer'
version = '0.1-SNAPSHOT'
description = """Diretas Ja"""
dependencies {
// your dependencies goes here, like this -->
// compile group: 'br.gov.governo', name: 'golpista', version:'2.0'
}
apply from: 'uploadArchives.gradle' // --> deploy configuration
3) inside uploadArchives.gradle (you need to create it):
configurations {
deployerJars
}
dependencies {
deployerJars "ar.com.synergian:wagon-git:0.2.5" // plugin
}
uploadArchives {
configuration = configurations.archives
repositories.mavenDeployer {
configuration = configurations.deployerJars
repository(url: "git:releases://https://YOUR_USERNAME:YOUR_APP_PASSWORD#bitbucket.org/YOUR_COMPANY/repo-release.git")
snapshotRepository(url: "git:snapshots://https://YOUR_USERNAME:YOUR_APP_PASSWORD#bitbucket.org/YOUR_COMPANY/repo-snapshot.git")
}
}
allprojects {
repositories {
mavenCentral()
maven { url "https://raw.github.com/synergian/wagon-git/releases"}
}
}
To deploy use:
gradle uploadArchives
TIP: beware the order of the entries... if you change it, it will break everything.
I know the question is old, but there isn't a lot of information on the topic, so I guess it is the right place to add some clues. I faced the same problems, there seemed to be no way to get it working. So there are some clues which might help:
As already been said, this whole maven plugin wagon thingy uses SSH to connect to repository (Bitbucket in my case). So you need to check a few things:
that Bitbuchet knows about your SSH key.go to your profile settings(not repository settings!) -> SSH keys and put there your public key received by keygen. There is instruction in the little 'insert key' window on Bitbucket to help you out.
that you have added your private key generated by keygen to your ssh agent (type ssh-add ~/.ssh/id_rsa fot Linux and probably mac)
also add credentials to your repository element:
repository(url: 'git:releases://git#bitbucket.org:gendalf/repo.git'){
authentication(userName: "gendalf", password: "swordfish") }
That plugin won't get confuzed about your output file. When I started to try uploading my library to the repository, I had flavors in it, so plugin didn't know which variant to select and selected nothing (apparently).
this stuff doesn't work with flavors as far as I know. So if you have flavors in the library which you are posting to private repository... consider getting rid of flavors. You probably don't need them anyway.
if you tried other publishing plugins before trying out maven (for example maven-publish), comment out all the script related to other stuff or delete it. My gradle was confused because of the additional scripts.
Consider trying out this https://jeroenmols.com/blog/2016/02/05/wagongit/ solution. It's what I used to finally publish, although it is pretty confusing about checking out from your just-created repository. Don't check out. Create the repository and publish right after that.
I hope this helps.
I want to install android library project to local maven repository.
Here is build.gradle:
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath 'com.android.tools.build:gradle:0.5.+'
}
}
apply plugin: 'android-library'
apply plugin: 'maven'
version = "1.0.0-SNAPSHOT"
group = "com.example"
repositories {
mavenCentral()
}
android {
compileSdkVersion 18
buildToolsVersion "17.0.0"
defaultConfig {
minSdkVersion 9
targetSdkVersion 18
}
}
When I run:
gradle install -i
it gets stuck here:
Executing task ':project:installTest' due to:
Task has not declared any outputs.
Starting process 'command 'd:\android-sdk-windows\platform-tools\adb.exe''. Working directory: D:\Projects\java\....... Command: d:\android-sdk-windows\platform-tools\adb.exe install -r D:\Projects\java\.......\build\apk\project.apk
An attempt to initialize for well behaving parent process finished.
Successfully started process 'command 'd:\android-sdk-windows\platform-tools\adb.exe''
> Building > :project:installTest
So first thing I noticed is that it's trying for some odd reason to deploy it on a device as APK.
Am I doing something wrong or is it just android-library plugin not compatible with maven plugin?
Edit: Please refer to the github page (https://github.com/dcendents/android-maven-gradle-plugin) for the latest instructions and find the correct version to use. The original instructions are not suitable anymore with the latest gradle release.
Original Post:
I've modified the maven plugin to be compatible with android library projects. See the project on github: https://github.com/dcendents/android-maven-gradle-plugin
Configure your android library projects to use it:
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath 'com.github.dcendents:android-maven-plugin:1.0'
}
}
apply plugin: 'android-library'
apply plugin: 'android-maven'
Then you should be able to install aar into your local maven repository using the install task.
Hope this helps, if you find issues with the plugin please let me know on github and I'll fix it.
Elaborating on CyclingSir's answer, I propose to add a separate "installArchives" task. This should also take care of picking up your custom artifacts (e.g. sources).
apply plugin: 'maven'
task installArchives(type: Upload) {
description "Installs the artifacts to the local Maven repository."
configuration = configurations['archives']
repositories {
mavenDeployer {
repository url: repositories.mavenLocal().url
}
}
}
Note that with Gradle Android plugin v0.5.5, gradle install still tries to install something on a device.
There's an easier solution if you don't want to use a custom plugin. Instead, just recreate the install task with a different name. I called it installArchives. Add the following code to your build.gradle:
task installArchives(type: Upload) {
description "Installs the artifacts to the local Maven repository."
repositories.mavenInstaller {
configuration = configurations.default
pom.groupId = 'my.group'
pom.artifactId = 'my-artifact'
pom.version = '1.0.0'
}
}
You can now run gradle installArchives to install your aar locally.
UPDATE 2014-11-26
The answer below made sense at the time of writing, when Android Build Tools were at version 0.5.5. It is most likely outdated now and probably does not work anymore.
I have personally switched my projects to use android-maven-plugin as described in the answer above, the plugin works fine with the recent versions of Android Build Tools too.
THE ORIGINAL ANSWER FROM FEBRUARY 2014
Publishing as AAR
If you don't mind using an older version of com.android.tools.build:gradle (i.e. 0.5.4), you can use the approach described in this blogpost. Not that according to the discussion in adt-dev mailing-list, this does not work in 0.5.5.
Add the following lines to your build.gradle:
apply plugin: 'maven-publish'
// load bundleRelease task
// this will not load the task in 0.5.5
android.libraryVariants
publishing {
publications {
maven(MavenPublication) {
artifact bundleRelease
}
}
}
To publish to your local maven repo, call this command:
gradle publishToMavenLocal
Publishing as JAR
If your Android Library does not have custom resources and can be published as JAR, then you can use the following build.gradle that works even with 0.5.5.
// build JAR file
task androidReleaseJar(type: Jar, dependsOn: assembleRelease) {
from "$buildDir/classes/release/"
}
apply plugin: 'maven-publish'
publishing {
publications {
maven(MavenPublication) {
artifact androidReleaseJar
}
}
}
To publish to your local maven repo, call this command:
gradle publishToMavenLocal
I just solved the issue by defining an upload archive as described here:
Gradle documentation 52.6.2. Deploying to a Maven repository
uploadArchives {
repositories {
mavenDeployer {
repository(url: "file://${System.env.HOME}/.m2/repository/")
}
}
}
calling
gradle uploadArchives
deploys the artefact to the (in my case local) Maven repo.
I havn't found a simple and more flexible way to specify the local repo's url with e.g. mavenLocal() yet but the above suits my needs.
I am migrating from Eclipse & maven to Android Studio & Gradle build.
My project structure now in Android Studio looks like this:
MyApp
->LibModule
-src
-...
-lib_repo/
-build.gradle
->AnotherModule
...
LibModule is my library module, I want to install the build jar of LibModule to my local maven repository. What I tried in build.gradle (under LibModule/ )is:
apply plugin: 'android-library'
apply plugin: 'maven'
...
group = 'com.my.lib'
uploadArchives {
repositories {
description "Installs the artifacts to the local Maven repository."
mavenDeployer {
repository(url: "file://${System.properties['user.home']}/.m2/repository")
pom.version = '1.1.0'
pom.artifactId = 'MyLib'
}
}
}
}
I also tried:
install {
repositories.mavenInstaller {
pom.version = '1.1.0'
pom.artifactId = 'MyLib'
}
}
I got error "unsupported Gradle DSL method found 'install()'! ".
When I build it in Android Studio IDE, in gradle console, I didn't see anything happen to upload the archive to my local maven repository. I also checked the content of build/ directory, there is no poms/ folder at all. It seems it is not triggered, I followed the gradle document here. Why? What is wrong?
For installing to the local Maven repository (which is mainly useful when exchanging artifacts with local Maven builds), use the install task rather than uploadArchives. For details, check the Gradle User Guide.