“This is the third day of my participation in the November Gwen Challenge. Check out the details: The Last Gwen Challenge 2021
preface
In our project architecture, there must be some basic modules that can be used in multiple apps. In this case, we generally package these modules into Android Library for unified maintenance and upload them to the warehouse for other groups to use. Repositories can choose from public repositories such as mavenCentral, but we generally choose to build our own Maven private repositories such as Sonatype Nexus. This article provides step-by-step instructions on how to publish the Android Library to maven’s private repository.
Add the Maven repository configuration
Add the private repository configuration to gradle.properties in the root directory of the project as follows:
Package information (package name, and Maven'sgroup, required) PROJ_GROUP=com.xxx. XXX # Description of the project (descriptive information, does not affect maven uploads) PROJ_WEBSITEURL= HTTP://xxxxx
PROJ_ISSUETRACKERURL=http://xxxxxPROJ_VCSURL= XXXXX PROJ_DESCRIPTION= XXXX # License information (strictly fill in The following, do not change) PROJ_LICENCE_NAME=The Apache Software License, Version2.0
PROJ_LICENCE_URL=http:/ / www.apache.org/licenses/LICENSE-2.0.txtProject licence_dest =repo # Developer info DEVELOPER_ID= XXXX DEVELOPER_NAME= XXXX [email protected] # repository address (local repository address to commit) # snapshot library SNAPSHOT_REPOSITORY_URL=http://xxxx/nexus/content/repositories/snapshots/# RELEASE_REPOSITORY_URL= HTTP://xxxx/nexus/content/repositories/releases/
Copy the code
This information is configured in the root directory of gradle.properties because we can have multiple Android libraries that need to be uploaded to Maven in a project so that we don’t have to configure them in each module.
There is also the need to configure the username and password, but since this is sensitive information, we usually put it in local.properties, and this file will be ignored by Git so it won’t be uploaded to the repository
#maven USERNAME= XXXX #maven PASSWORD= XXXXCopy the code
Gradle. properties in Android Library:
# Name (preferably the same as PROJ_ARTIFACTID) PROJ_NAME= XXX # Module name (artifactId for Maven) PROJ_ARTIFACTID= XXXX PROJ_POM_NAME=Local RepositoryCopy the code
Writing release code
Start by adding the Maven plugin to build.gradle in the Android Library
apply plugin: 'maven'
Copy the code
Then you can write the release code, the complete code is as follows:
def isReleaseBuild() {
return android.defaultConfig.versionName.contains("SNAPSHOT") = =false
}
def sonatypeRepositoryUrl
if (isReleaseBuild()) {
sonatypeRepositoryUrl = RELEASE_REPOSITORY_URL
} else {
sonatypeRepositoryUrl = SNAPSHOT_REPOSITORY_URL
}
afterEvaluate { project ->
uploadArchives {
repositories {
mavenDeployer {
//beforeDeployment { MavenDeployment deployment -> signing.signPom(deployment) }
pom.artifactId = PROJ_ARTIFACTID
Properties properties = new Properties()
properties.load(project.rootProject.file('local.properties').newDataInputStream())
repository(url: sonatypeRepositoryUrl) {
authentication(userName: properties.getProperty("USERNAME"), password: properties.getProperty("PASSWORD"))
}
pom.project {
name PROJ_NAME
groupId PROJ_GROUP
version android.defaultConfig.versionName
// scm {
// url POM_SCM_URL
// connection POM_SCM_CONNECTION
// developerConnection POM_SCM_DEV_CONNECTION
/ /}
licenses {
license {
name PROJ_LICENCE_NAME
url PROJ_LICENCE_URL
distribution PROJ_LICENCE_DEST
}
}
developers {
developer {
id DEVELOPER_ID
name DEVELOPER_NAME
}
}
}
}
}
}
// signing {
// required { isReleaseBuild() && gradle.taskGraph.hasTask("uploadArchives") }
// sign configurations.archives
/ /}
task androidJavadocs(type: Javadoc) {
failOnError false
source = android.sourceSets.main.java.source
options {
links "http://docs.oracle.com/javase/7/docs/api/"
linksOffline "http://d.android.com/reference"."${android.sdkDirectory}/docs/reference"
}
classpath+ =project.android.libraryVariants.toList().first().javaCompile.classpath
classpath+ =project.files(android.getBootClasspath().join(File.pathSeparator))
}
task androidJavadocsJar(type: Jar, dependsOn: androidJavadocs) {
classifier = 'javadoc'
//basename = artifact_id
from androidJavadocs.destinationDir
}
task androidSourcesJar(type: Jar) {
classifier = 'sources'
from android.sourceSets.main.java.srcDirs
}
artifacts {
//archives packageReleaseJar
archives androidSourcesJar
archives androidJavadocsJar
}
}
Copy the code
Publish to the Maven repository
Select the Module you want to publish from gradle on the right side of Android Studio, find the task you want to publish, double-click it and run it, as shown in the figure below
Handling multiple Android Library release issues
As mentioned above, it is possible to maintain multiple Android libraries simultaneously in a project, but following the above steps will fail when releasing. The problem is as follows:
Could not transfer artifact xxx from/to remote (http://xxx): Failed to transfer file: http://xxx. Return code is: 400, ReasonPhrase: Bad Request.
A close look at the Gradle log shows that when we publish one of the Android libraries in the above way, all the Android libraries in the project are recompiled and published, but the other Android libraries are not changed, so there are no updates. The Maven repository will return the above error if it finds that the same version has been released (usually a release repository has this setting to prevent misoperation from causing problems).
One solution is to publish by command:
./gradlew xxx:uploadArchives
Copy the code
Here XXX is the module name, so only this module will be compiled and published.
We can also fix this problem by modifying the release code and adding a task to build.gradle:
task mavenUploadxxx (dependsOn: uploadArchives){
group 'upload'
}
Copy the code
Similarly, here XXX is replaced with the module name. Here, we put this task in the group upload. If it is not set, it will be put in the other group by default, but there are many tasks in this group, so it is not convenient to find.
After sync, you will find a mavenUploadxxx task in the Upload group of the corresponding Module in the Gradle panel. Double-click this task to compile and publish only the Android Library.
Use the Library
It’s easier to use, adding the repository first
allprojects {
repositories{... maven { url'http://xxx/nexus/content/groups/public/'}}}Copy the code
Then add the dependencies to your project’s build.gradle.
The problem summary
In this process, we also encountered some problems. Here is a brief summary:
Error 400 is returned when publishing to Snapshot:
Return code is: 400, ReasonPhrase: Bad Request.
This is because the version name is incorrect. The version format to be released to Snapshot must be x.x.x-snapshot, where “-snapshot” must follow. Otherwise, error 400 will be reported.
Note: Errors such as “-snapshot” in the release version will also be reported; Release does not allow repeated publishing, so if you already have this version of the project, re-publishing will cause an error, whereas Snapshot generally supports repeated publishing
Error 401 when publishing:
Return code is: 401, ReasonPhrase: Unauthorized
This is because the username and password are not configured, or are incorrectly configured. Sonatype Nexus Default user name admin Password Admin123, but you are advised to change it in time.
3, Sonatype Nexus warehouse:
Public: warehouse group. Proxy other repositories for external references. (That is, if you are importing projects using Maven, the Maven center is configured as the URL for this repository.)
Snapshot: indicates the snapshot library. The user name and password are required for submitting a snapshot version.
Release: official library. The user name and password are required for submitting the official version.