Android Library Gradle release JAR
Solution 1
While I haven't tried uploading the artifacts with a deployment to Sonatype (or even a local repo), here's what I managed to come up with a few weeks ago when trying to tackle the same problem.
android.libraryVariants.all { variant ->
def name = variant.buildType.name
if (name.equals(com.android.builder.core.BuilderConstants.DEBUG)) {
return; // Skip debug builds.
}
def task = project.tasks.create "jar${name.capitalize()}", Jar
task.dependsOn variant.javaCompile
task.from variant.javaCompile.destinationDir
artifacts.add('archives', task);
}
Then run the following:
./gradlew jarRelease
Solution 2
Another way to generate a jar from a library project through gradle is as follows:
In your library's build.gradle:
def jarName = 'someJarName.jar'
task clearJar(type: Delete) {
delete "${project.buildDir}/libs/" + jarName
}
task makeJar(type: Copy) {
from("${project.buildDir}/intermediates/bundles/release/")
into("${project.buildDir}/libs/")
include('classes.jar')
rename('classes.jar', jarName)
}
makeJar.dependsOn(clearJar, build)
What we are doing here is just copying the classes.jar generated by the Android Gradle plugin. Be sure to look into your build directory for this file and see if its contents are in the way you want.
Then run the makeJar
task and the resulting jar will be in library/build/libs/${jarName}
.jar
The will have the class files according to your configuration for release. If you are obfuscating it, then the files in the jar will be obfuscated.
Marek Sebera
Updated on December 28, 2020Comments
-
Marek Sebera over 3 years
How can I release Jar packaging of
android-library
project?
I've found, classes.jar is located underbuild/bundles/release/classes.jar
and I suppose this is correct Jar package (contains*.class
files).Is there some official way, to release library as JAR instead of AAR ?
Edit
I use Gradle to release Maven artifacts, and I'd like to release JAR along with AAR package. So JAR with signature, md5, manifest, ...
based on https://chris.banes.me/2013/08/27/pushing-aars-to-maven-central/apply plugin: 'maven' apply plugin: 'signing' configurations { archives { extendsFrom configurations.default } } def sonatypeRepositoryUrl if (isReleaseBuild()) { println 'RELEASE BUILD' sonatypeRepositoryUrl = "https://oss.sonatype.org/service/local/staging/deploy/maven2/" } else { println 'DEBUG BUILD' sonatypeRepositoryUrl = "https://oss.sonatype.org/content/repositories/snapshots/" } if(!hasProperty('nexusPassword')) { ext.set('nexusPassword', System.console().readPassword("\n\$ Type in password for Sonatype nexus account " + nexusUsername + ": ")) } if(!signing.hasProperty('password')) { ext.set('signing.password', System.console().readPassword("\n\$ Type in GPG key password: ")) } afterEvaluate { project -> uploadArchives { repositories { mavenDeployer { beforeDeployment { MavenDeployment deployment -> signing.signPom(deployment) } pom.artifactId = POM_ARTIFACT_ID repository(url: sonatypeRepositoryUrl) { authentication(userName: nexusUsername, password: nexusPassword) } pom.project { name POM_NAME packaging POM_PACKAGING description POM_DESCRIPTION url POM_URL scm { url POM_SCM_URL connection POM_SCM_CONNECTION developerConnection POM_SCM_DEV_CONNECTION } licenses { license { name POM_LICENCE_NAME url POM_LICENCE_URL distribution POM_LICENCE_DIST } } developers { developer { id "loopj" name "James Smith" } developer { id "smarek" name "Marek Sebera" } } } } } } signing { required { isReleaseBuild() && gradle.taskGraph.hasTask("uploadArchives") } sign configurations.archives } task androidJavadocs(type: Javadoc) { source = android.sourceSets.main.java.srcDirs } task androidJavadocsJar(type: Jar) { classifier = 'javadoc' from androidJavadocs.destinationDir } task androidSourcesJar(type: Jar) { classifier = 'sources' from android.sourceSets.main.java.srcDirs } artifacts { archives androidSourcesJar archives androidJavadocsJar } }
using
task androidJar(type: Jar) { from android.sourceSets.main.java.srcDirs }
will package only java files, not compiled and linked against android sdk
-
Marek Sebera over 10 yearsI'm afraid, this is correct answer :-) Thanks, I'll post final edit I've made to get it work
-
CommonsWare over 10 yearsI can also confirm that this works. Note that the generated task does not show up when running
gradle tasks
, only withgradle tasks --all
. Thanks again! -
Sam about 10 yearsThanks this does help, but it still doesn't generate the class files for dependencies. I'm trying to make an SDK jar basically that will be a single jar to pass out, but this compile does not include module projects that it is dependent on and does not pull down jars from the dependency section etc.. Do you have any suggestions to accomplish this where it compiles the library projects into the jar as well so I don't have to hand out 4 jars, one for each library project. Then it would be nice to figure out how to include the maven dependency jars too like Gson or Otto.
-
Kevin almost 10 yearsThis seems to break for me when I add flavors because it tries to create several of the same named tasks without a flavor included. I'm no Groovy guy and cannot figure out how to add the flavor to the task name. I'd appreciate any hints on how to do that.
-
Piklor almost 10 yearsI had a small addition to Jake's solution that accounts for any java resources - add
task.dependsOn variant.processJavaResources
andtask.from variant.processJavaResources.destinationDir
(sorry, couldn't work out how to format this properly) -
MikeL over 9 yearsCan someone point out how can I use proguard with this configuration? It seems that defining the buildTypes with proguard does not apply.
-
dbm over 9 years@Kevin, I exchanged the
"jar${name.capitalize()}"
part with"jar${variant.name.capitalize()}"
to make the task account for the flavour name too (thevariant.name
is composed from both buildType name and productFlavor name) -
Jani over 9 years@SamDozor please follow the link for proguard support survivingwithandroid.com/2014/05/…
-
keno about 9 years@Piklor, I tried adding your lines for getting the resources included but it didn't work. Could you mention the entire task code you used please
-
Piklor about 9 years@keno, unfortunately I can't locate the code in question.
-
2cupsOfTech over 8 yearsit seems this is not going to package a .png resource into the .jar, is there a way to package an image resource into the jar ?
-
2cupsOfTech over 8 years@CommonsWare any thoughts on packaging images with gradle into jar?
-
CommonsWare over 8 years@2cupsOfTech: Well, you can't put Android resources into a JAR, only an AAR. You're welcome to play around with classic Java resources in the JAR, but I have not tried it, and it's not commonly done.
-
2cupsOfTech over 8 years@CommonsWare this script doesn't produce an obfuscated jar I believe, is that possible to do?
-
CommonsWare over 8 years@2cupsOfTech: Beats me
-
2cupsOfTech over 8 years@jake-wharton how to build an obfuscated jar using your script?
-
Olinasc over 8 years@2cupsOfTech to generate an obfuscated jar I used the alternative method of copying the Jar that is already generated by the library build in /build/intermediates/bundles/release (as mentioned by Jani). I guess Jani should an alternative answer here. It works for both obfuscated and non obfuscated libraries and seems simpler to me.
-
Olinasc over 8 years@Jani you should post an answer here with your alternative method. It would help others as it also handles obfuscated cases.
-
2cupsOfTech over 8 years@Olinasc I ended up writing a small shell script to convert a jar to an obfuscated jar using proguard
-
Olinasc over 8 years@2cupsOfTech I understand. This seems though as more work than is needed. I will post the alternative answer here if Jani does not reply.
-
2cupsOfTech over 8 years@Olinasc its a 1 line script, look into command: 'java -jar -outjars -injars', my script is not general otherwise I would post, this link could be helpful: proguard.sourceforge.net/manual/examples.html
-
Jani over 8 years@2cupsOfTech I no longer have access to the build.gradle file that I used this alternative method. Please post the answer. I'm sorry for the inconvenience.
-
Jasper de Vries over 2 yearsI'm getting
WARNING: API 'variant.getJavaCompile()' is obsolete and has been replaced with 'variant.getJavaCompileProvider()'.
When I replace it,destinationDir
is not found.