Bundling all dependencies in .aar file - maven

I have an SDK project that is referencing quit alot of dependencies in gradle. I have to ask the SDK users to add those dependencies when they use the SDK in their projects. The problem is, every time I add some new dependency or replace current dependency with a new one, I'll have to ask the users to make changes as well, which is not a good practice in my opinion. Is there a way to bundle all the dependencies in the .aar. I am generating the artifact file with the following code.
uploadArchives{
repositories.mavenDeployer {
def deployPath = file(getProperty('aar.deployPath'))
repository(url: "file://${deployPath.absolutePath}")
pom.project {
groupId 'myPackageName'
artifactId 'wingoku-io'
version "0.0.6"
}
}
These are my dependencies:
dependencies {
compile 'com.github.nkzawa:socket.io-client:0.5.0'
compile 'com.android.support:cardview-v7:21.+'
compile 'de.greenrobot:eventbus:2.4.0'
}
EDIT:
I have added the following method in uploadArchives method. The size of the artifact file has increased but when I use the .aar file in app project, it can't find the files.
uploadArchives{
repositories.mavenDeployer {
def deployPath = file(getProperty('aar.deployPath'))
repository(url: "file://${deployPath.absolutePath}")
pom.project {
groupId 'myPackageName'
artifactId 'wingoku-io'
version "0.0.6"
}
**configurations.all {
transitive = true
}**
}
UPDATE:
I tried the following code because #aar was generating errors (couldn't find xx.xx.xx.aar on jcenter()). This still fails, the d
compile ('com.github.nkzawa:socket.io-client:0.5.0'){
transitive=true
}
compile ('com.android.support:cardview-v7:21.+#aar'){
transitive=true
}
compile ('de.greenrobot:eventbus:2.4.0'){
transitive=true
}
Dalvik throws following warnings for all classes:
dalvikvm﹕ Link of class 'Lio/wingoku/sdk/Fetch$6;' failed
It eventually throws exception ClassDefNotFound

Regarding your edit
configurations.all {
transitive = true
}
I'm not sure it as any effect.
I think you should write something like this:
dependencies {
compile 'com.github.nkzawa:socket.io-client:0.5.0'{
transitive=true
}
compile 'com.android.support:cardview-v7:21.+#aar'{
transitive=true
}
compile 'de.greenrobot:eventbus:2.4.0'{
transitive=true
}
}
It just say that
cardview is aar to include in this library.
eventbus and socket.io-client are jar lib to include in aar

Related

How to define dependency version only once for whole Gradle multi-module project?

I made a decision to migrate from Dependency Management Plugin to Gradle built-in BOM import support. Since Gradle built-in BOM import support has better performance But
I run into the issue:
I cannot find alternatives for dependency and dependencySet in native Gradle:
dependencyManagement {
dependencies {
dependency("org.springframework:spring-core:4.0.3.RELEASE")
}
}
//or
dependencyManagement {
dependencies {
dependencySet(group:'org.slf4j', version: '1.7.7') {
entry 'slf4j-api'
entry 'slf4j-simple'
}
}
}
and then I could use dependency without version
dependencies {
compile 'org.springframework:spring-core'
}
How can I get the same behavior in naive Gradle? I mean: I'd like to define a version once as I did it when using Dependency Management Plugin
Solution below helps to avoid versions copy-paste. However it isn't the same with Dependency Management plugin.
For Gradle Kotlin Dsl:
You can create buildSrc with you own code, when you can place any constants.
Algorithm:
Create folder buildSrc/src/main/kotlin
Create file buildSrc/src/main/kotlin/Versions.kt with content:
object Versions {
const val junitVersion = "5.5.5" // just example
}
Create file buildSrc/build.gradle.kts with content:
plugins {
`kotlin-dsl`
}
Use the following syntax in your gradle.kts files:
dependencies {
testImplementation("org.junit.jupiter:junit-jupiter:${Versions.junitVersion}")
}
For Gradle Groovy:
Create file gradle.properties
Put versions there with syntax like okhttp_version=4.2.0
Use the following syntax in your gradle files:
dependencies {
compile group: 'com.squareup.okhttp3', name: 'okhttp', version: okhttp_version
}
You can do so on the gradle.properties file. I.e.:
# APPLICATION PROPERTIES
name=projectName
group=com.domain
version=1.0.0
description=A brief description
gradleScripts=https://raw.githubusercontent.com/hexagonkt/hexagon/1.2.0/gradle
# DEPENDENCIES VERSIONS
kotlinVersion=1.3.61
kotlinCoroutinesVersion=1.3.2
Or in settings.gradle if you don't want to create another file:
rootProject.name = "hexagon-contact-application"
gradle.rootProject {
allprojects {
version = "1.0.0"
group = "org.hexagonkt"
description = "Contact application backend api"
}
extensions.gradleScripts = "https://raw.githubusercontent.com/hexagonkt/hexagon/1.0.18/gradle"
extensions.kotlinVersion = "1.3.50"
extensions.kotlinCoroutinesVersion = "1.3.2"
extensions.hexagonVersion = "1.0.21"
extensions.logbackVersion = "1.2.3"
extensions.bcryptVersion="0.8.0"
extensions.javaJwtVersion="3.8.2"
}
And if you want to avoid adding the version variable to all related dependencies, you can create a method in the build file:
plugins {
id 'org.jetbrains.kotlin.jvm' version '1.3.50'
}
apply from: "$gradleScripts/kotlin.gradle"
apply from: "$gradleScripts/service.gradle"
apply from: "$gradleScripts/junit.gradle"
defaultTasks("test")
mainClassName = 'com.hexagonkt.contact.ApplicationKt'
applicationDefaultJvmArgs = ["-Xms64M", "-Xmx2G", "-XX:+UseNUMA", "-XX:+UseParallelGC"]
dependencies {
httpkt(it, "http_server_jetty")
httpkt(it, "store_mongodb")
httpkt(it, "hexagon_web")
implementation("at.favre.lib:bcrypt:$bcryptVersion")
implementation("com.auth0:java-jwt:$javaJwtVersion")
testImplementation("com.hexagonkt:port_http_client:$hexagonVersion")
}
private void httpkt(final def dependencies, final String artifact) {
dependencies.implementation("com.hexagonkt:$artifact:$hexagonVersion")
}

Adding external source files to a kotlin project

I have Kotlin sources located at, say, repo/project_a/src/. I created a Kotlin Gradle project in IntelliJ IDEA, located at repo/project_b/.... And I can't for the life of me figure out how to add the sources. If I add them through project structure menu it works fine, but as soon as it wants to re-read the gradle file id deletes the structure (It warns as much in the UI).
This is my gradle file:
plugins {
id 'org.jetbrains.kotlin.jvm' version '1.2.70'
}
group 'cli'
version '1.0'
repositories {
mavenCentral()
}
dependencies {
compile "org.jetbrains.kotlin:kotlin-stdlib-jdk8"
}
compileKotlin {
kotlinOptions.jvmTarget = "1.8"
}
I've tried adding all variations of
sourceSets {
main {
kotlin {
srcDirs += "repo/project_a/"
}
}
}
But it does absolutely nothing.
Any ideas?
The path you are giving to Gradle will compile to the current project path plus "repo/project_a/". Try with:
sourceSets {
main {
kotlin {
srcDirs += "../project_a/"
}
}
}

Unable to resolve library using Gradle. Resolved using Grape

I'm fairly new to Groovy and I'm trying to wrap my head around Gradle. If I import the org.jvnet.hudson.plugins through Grapes it works perfectly and the dependency is resolved. But if I try to retrieve the dependency using Gradle the dependency is not resolved.
The package org.eclipse.hudson:hudson-core:3.2.1 works with both Gradle and Grape.
A dependency that is not resolved using Gradle
compile 'org.jvnet.hudson.plugins:checkstyle:3.42'
A dependency which is resolved using Grape
#Grab('org.jvnet.hudson.plugins:checkstyle:3.42')
A dependency which is resolved using Gradle
compile 'org.eclipse.hudson:hudson-core:3.2.1'
Error during Gradle build
line 3, column 1.
import hudson.plugins.checkstyle.CheckStyleResultAction;
^
The build.gradle
apply plugin: 'groovy'
repositories {
mavenCentral()
maven {
url "http://repo.jenkins-ci.org/releases/"
}
}
configurations {
ivy
}
sourceSets {
main {
groovy {
srcDirs = ['src/']
}
}
test {
groovy {
srcDirs = ['test/']
}
}
}
dependencies {
compile 'org.codehaus.groovy:groovy-all:2.4.11'
compile "org.apache.ivy:ivy:2.4.0"
ivy "org.apache.ivy:ivy:2.3.0"
// Works
compile 'org.eclipse.hudson:hudson-core:3.2.1'
// Does not work
compile 'org.jvnet.hudson.plugins:checkstyle:3.42'
}
tasks.withType(GroovyCompile) {
groovyClasspath += configurations.ivy
}
You're probably not actually downloading the jar you think you are. Looks like the default artifact that comes back from the org.jvnet.hudson.plugins:checkstyle:3.42 dependency is actually a file named checkstyle-3.42.hpi.
To get the jar which contains the classes instead, use:
compile group: 'org.jvnet.hudson.plugins', name: 'checkstyle', version:'3.42', ext: 'jar'
Then that class will be found on your classpath (and you'll be on to locating the next missing dependency).

gradle protobuf plugin not functioning

I am using the below mentioned protobuf gradle plugin in one project where its working fine but when I referenced the same plugin in a different project, 'gradle clean' is consistently giving me the error copied below:
relevant parts of build.grade (v3.4)
apply plugin: 'com.google.protobuf'
buildscript {
repositories {
mavenCentral()
mavenLocal()
jcenter()
}
dependencies {
// classpath "net.ltgt.gradle:gradle-errorprone-plugin:0.0.9"
// classpath 'com.github.jengelman.gradle.plugins:shadow:1.2.4'
classpath 'com.google.protobuf:protobuf-gradle-plugin:0.8.0'
}
}
def grpcVersion = '1.1.2'
dependencies {
compile "io.grpc:grpc-netty:${grpcVersion}"
compile "io.grpc:grpc-protobuf:${grpcVersion}"
compile "io.grpc:grpc-stub:${grpcVersion}"
}
protobuf {
protoc {
Artifact = 'com.google.protobuf:protoc:3.2.0'
}
plugins {
grpc {
Artifact = "io.grpc:protoc-gen-grpc-java:${grpcVersion}"
}
}
generateProtoTasks {
all()*.plugins {
grpc {
// To generate deprecated interfaces and static bindService method,
// turn the enable_deprecated option to true below:
option 'enable_deprecated=false'
}
}
}
}
error when I run gradle clean
* What went wrong:
Could not compile build file '/xyz/xyz/build.gradle'.
> startup failed:
build file '/xyz/xyz/build.gradle': 102: you tried to assign a value to the class 'org.gradle.api.component.Artifact'
# line 102, column 9.
Artifact = 'com.google.protobuf:protoc:3.2.0'
^
build file '/xyz/xyz/build.gradle': 106: you tried to assign a value to the class 'org.gradle.api.component.Artifact'
# line 106, column 13.
Artifact = "io.grpc:protoc-gen-grpc-java:${grpcVersion}"
I have tried protobuf plugins 0.8.0. and 0.8.1 but both give the same error. v0.8.0 works as is in a different project. Any thoughts on how to troubleshoot this further would be appreciated.
It should be artifact, not Artifact. The latter is a class that you try to assign to which will not work, the former is a property you assign to.

How to import dependecies from build.gradle to pom.xml

I use maven-publish plugin for deploying android library(.aar).
My library has another dependencies, which are also .aar
How can I import all dependencies from build.gradle, dependencies section:
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
compile 'com.android.support:appcompat-v7:23.1.1'
compile 'com.android.support:design:23.1.1'
compile 'com.android.support:support-v4:23.1.1'
compile ('com.android.support:recyclerview-v7:22.2.1'){
exclude group: 'com.android.support', module: 'support-v4'
}
compile 'com.inthecheesefactory.thecheeselibrary:stated-fragment-support-v4:0.10.0'
//Http communication, websockets, etc.
compile 'com.squareup.okhttp:okhttp:2.4.0'
compile 'com.squareup.retrofit:retrofit:1.9.0'
//Fonts
compile 'uk.co.chrisjenx:calligraphy:2.1.0'
//Unit tests
testCompile 'junit:junit:4.12'
testCompile 'org.mockito:mockito-core:1.9.5'
//Other
compile ('org.apache.commons:commons-lang3:3.4'){
exclude group: 'org.apache.httpcomponents'
}
//Reactive programmnig
compile 'io.reactivex:rxjava:1.0.13'
compile 'io.reactivex:rxandroid:0.25.0'
compile 'com.github.bumptech.glide:glide:3.6.1'
}
To generated pom.xml dependencies section:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.my.sdk</groupId>
<artifactId>SDK</artifactId>
<version>0.0.1</version>
<packaging>aar</packaging>
<dependencies>
...
</dependencies>
</project>
I found some explanation how to do similar things:
Optional Gradle dependencies for Maven libraries
How to change artifactory runtime scope to compile scope?
https://issues.gradle.org/browse/GRADLE-1749
http://www.scriptscoop.net/t/6ac07fb41846/how-to-maven-publish-a-gradle-project-jar-with-provided-scope.html
So, I understood, that I should use pom.withXml, import all dependecies from project.configurations.compile.allDependencies with scope compile, and put it into asNode().dependencies
But I'm not familiar with it, and I think I doing something wrong. Here is my current code:
publishing {
publications {
maven(MavenPublication) {
artifact "${project.buildDir}/outputs/aar/${project.name}-release.aar"
artifactId = POM_ARTIFACT_ID
groupId = GROUP
version = VERSION_NAME
// Task androidSourcesJar is provided by gradle-mvn-push.gradle
//artifact androidSourcesJar {
// classifier "sources"
//}
pom.withXml {
def depsNode = asNode().dependencies.'*'
project.configurations.compile.allDependencies.each { dep ->
if(dep.name != null && dep.group != null && dep.version != null) {
def depNode = new Node(null, 'dependency')
def groupIdNode = new Node(depNode, 'groupId', dep.getGroup())
def artifactIdNode = new Node(depNode, 'artifactId', dep.getName())
def versionNode = new Node(depNode, 'version', dep.getVersion())
depsNode.add(depNode)
println depsNode
}
}
}
}
}
repositories {
maven {
credentials {
username System.getenv('NEXUS_USER_NAME')
password System.getenv('NEXUS_PASSWORD')
}
url "http://nexus-repo"
}
}
}
To publish a .aar library with the dependencies listed correctly in pom.xml, it might be easier to use this plugin, rather than assemble the dependencies section yourself using the maven-publish plugin.
To apply plugin:
plugins {
id "com.github.dcendents.android-maven" version "1.3"
}
and run task install to push library to local .m2 repo.
You can override the repo being published to like this:
install {
repositories {
mavenDeployer {
repository(...)
}
}
}
You can of course, continue to use the maven-publish plugin if you so prefer. In your code, you're looking for depsNode which does not already exist. You likely need to create a new Node for depsNode and add it to the pom first. Or just use append:
pom.withXml {
def depsNode = asNode().appendNode('dependencies')
configurations.compile.allDependencies.each { dep ->
def depNode = depsNode.appendNode('dependency')
depNode.appendNode('groupId', dep.group)
depNode.appendNode('artifactId', dep.name)
depNode.appendNode('version', dep.version)
//optional add scope
//optional add transitive exclusions
}
}
The caveat here is that, you still need to handle exclusions correctly. Also, if you have variants in your project, and have different compile configurations such as androidCompile or somethingElseCompile, you need to handle those correctly as well.
You can update the dependencies with the dependencies of another project or library in the maven publish task. This has to be done before jar generation task. In this way, the changes will be reflected in the pom generation and no need for pom xml manipulation. getDependencies is the method that you extract those dependencies and you should implement it ;)
This is the snippet in the publish task
artifactId = POM_ARTIFACT_ID
groupId = GROUP
version = VERSION_NAME
project.configurations.implementation.withDependencies { dependencies ->
dependencies.addAll(getDependencies(project))
}
from components.java

Resources