I have investigated a while and probably saw most popular answers here related to aar and transitive dependencies but somehow it is still not clear for me how to make this working.
So:
I have android library with given gradle config:
apply plugin: 'android-library'
apply plugin: 'android-maven'
version = "1.0.0"
group = "com.somepackage"
buildscript {
repositories {
mavenCentral()
mavenLocal()
}
dependencies {
classpath 'com.github.dcendents:android-maven-plugin:1.0'
}
}
android {
compileSdkVersion 19
buildToolsVersion '19.0.3'
defaultConfig {
minSdkVersion 10
}
}
repositories {
maven { url 'http://www.bugsense.com/gradle/' }
}
dependencies {
provided 'com.google.android.gms:play-services:+'
provided 'com.android.support:appcompat-v7:+'
compile 'com.google.code.gson:gson:2.2.4'
compile 'com.bugsense.trace:bugsense:3.6'
compile 'commons-net:commons-net:3.3'
}
Then I am deploying it to local maven repo with gradle install. POM file of the deployed library looks like this:
<?xml version="1.0" encoding="UTF-8"?>
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>
<groupId>com.sprezzat</groupId>
<artifactId>app</artifactId>
<version>1.0.0</version>
<packaging>aar</packaging>
<dependencies>
<dependency>
<groupId>com.bugsense.trace</groupId>
<artifactId>bugsense</artifactId>
<version>3.6</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>commons-net</groupId>
<artifactId>commons-net</artifactId>
<version>3.3</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.2.4</version>
<scope>compile</scope>
</dependency>
</dependencies>
</project>
And finally gradle config of my android application using above library as a dependency:
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath 'com.android.tools.build:gradle:0.9.+'
}
}
apply plugin: 'android'
repositories {
mavenCentral()
mavenLocal()
}
android {
compileSdkVersion 15
buildToolsVersion "19.0.2"
defaultConfig {
minSdkVersion 10
targetSdkVersion 18
}
}
dependencies {
compile 'com.google.android.gms:play-services:+'
compile 'com.android.support:appcompat-v7:+'
compile 'com.somepackage:LIBRARY_NAME:1.0.0#aar'
}
And after deploying application on phone I am getting NoClassDefFoundError for classes belonging to compile dependencies of my android library.
Inspecting my android application dependencies using gradle dependencies:
apk - Classpath packaged with the compiled main classes.
+--- com.google.android.gms:play-services:+ -> 4.3.23
| \--- com.android.support:support-v4:19.0.1 -> 19.1.0
+--- com.android.support:appcompat-v7:+ -> 19.1.0
| \--- com.android.support:support-v4:19.1.0
\--- com.somepackage:LIBRARY_NAME:1.0.0
According to above tree, all transitive dependencies are not detected. Where is the problem and how should it be done correctly?
I have solved my problem by setting transitive attribute for my aar dependency:
compile ('com.somepackage:LIBRARY_NAME:1.0.0#aar'){
transitive=true
}
you should not use "#aar", if use "#" is become "Artifact only notation", if you want to use "#" and want have dependence transitive, you should add "transitive=true"
Try this if you are using aar locally:
compile(project(:your-library-name)) {
transitive=true
}
I was having a similar problem and felt I could share the steps of solving the problem.
The basic idea of not being able to use the transitive dependencies while you are publishing your own aar is actually not having the .pom file generated with the expected transitive dependencies.
I was using 'maven-publish' plugin for my android aar dependency to publish it in my own private maven repository. The transitive dependencies were not resolved when my other projects were adding my aar dependency in their build.gradle. Hence here what I did to modify the .pom file while publishing my aar.
An important thing to note here that, the dependencies which you want to have the transitive behavior should be imported using the api in your library project's build.gradle file like the following.
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
api 'com.android.volley:volley:1.0.0'
api "com.google.code.gson:gson:$globalGsonVersion"
}
Now as I said earlier, I was using maven-publish plugin to publish the aar dependency and hence my publishing task in the gradle looks like the following.
publishing {
publications {
mavenAar(MavenPublication) {
from components.android
}
mavenJava(MavenPublication) {
pom.withXml {
def dependenciesNode = asNode().appendNode('dependencies')
// Iterate over the api dependencies (we don't want the test ones), adding a <dependency> node for each
configurations.api.allDependencies.each {
def dependencyNode = dependenciesNode.appendNode('dependency')
dependencyNode.appendNode('groupId', it.group)
dependencyNode.appendNode('artifactId', it.name)
dependencyNode.appendNode('version', it.version)
}
}
}
}
repositories {
maven {
// Your repository information goes here
}
}
}
Hence, I used another mavenJava task to publish the .pom file in my private maven repo so that when the aar file is added as a dependency to some other module, it gets the .pom information and download the transitive dependency.
To complete the answer, this is how you should add the dependency in the build.gradle file for your own published aar to me imported.
api('com.example.masudias:my_lib:1.0.0#aar') {
transitive = true
}
Transitive dependency
transitive means that the consumer(e.g. app) includes a producer and all producer's dependencies(e.g. libraries). It increase build time and can create some issues with dependency versions
By default, Gradle dependency has transitive = true
api ('com.package:library:0.0.1')
//the same
api ('com.package:library:0.0.1') {
transitive = true
}
When you use #artifact notation it has transitive = false
api ('com.package:library:0.0.1#aar')
//the same
api ('com.package:library:0.0.1#aar') {
transitive = false
}
For me complete publishing solution looks like this:
apply plugin: 'com.github.dcendents.android-maven'
group = GROUP
version = VERSION
// you could move it to env variable or property
def publishFlavorless = true
def firstTask = null
android.libraryVariants.all { variant ->
if (variant.name.toLowerCase().contains("debug")) {
// Workaround for https://github.com/gradle/gradle/issues/1487
if (publishFlavorless && firstTask == null) {
def bundleTask = tasks["bundle${variant.name.capitalize()}Aar"]
firstTask = bundleTask
artifacts {
archives(firstTask.archivePath) {
builtBy firstTask
name = project.name
}
}
}
return
}
def bundleTask = tasks["bundle${variant.name.capitalize()}Aar"]
artifacts {
archives(bundleTask.archivePath) {
classifier variant.flavorName
builtBy bundleTask
name = project.name
}
}
}
install {
repositories.mavenInstaller {
// This generates POM.xml with proper parameters
pom.project {
name POM_NAME
artifactId POM_ARTIFACT_ID
// For aar it is equal to 'aar' with jar transitive dependencies won't work
packaging POM_PACKAGING
description POM_DESCRIPTION
}
}
}
The transitive = true block is required as well ...
AAR file doesn't contain transitive dependencies. So even if use api instead of implementation it wont work.
In our team we had developed a library to use in our applications and we wanted it to be for internal use only. Earlier we used to include whole module that seems to work. Later we decided to move to aar file but we were also facing same issue of classpath not found. After some research we came to know that we can also use local maven repo. We decided to use that.
Here is step by step process
Publishing repo
1.In your Library's root build.gradle file you need to include
id 'com.github.dcendents.android-maven' version '2.0' apply false
2.In you library's module level build.gradle file you need to add
a) In plugins
id 'maven-publish'
b) At bottom of gradle file add
publishing {
publications {
release(MavenPublication) {
groupId = 'com.demo.android'
artifactId = 'qrcodescanner'
version = '1.0.0'
afterEvaluate {
from components.release
}
}
}
repositories {
maven {
name = "qrcodescanner"
url = "${project.buildDir}/repo"
}
}
}
3.Depends on the name you have given a gradle tasks will be generated you can check using gradlew tasks or by using gradle window at top right corner in android studio, Our was
publishReleasePublicationToQrcodescannerRepository
4.Run it and repo will be generated in given path
gradlew publishReleasePublicationToQrcodescannerRepository
Final step you need to publish it to maven local using
gradlew publishToMavenLocal
if it doesn't work you can try gradlew clean and gradlew build before executing it.
Using local repo
1.You need to add mavenLocal() in root level build.gradle file of your project you wanted to use it in like this before other central repos
allprojects {
repositories {
mavenLocal()
google()
jcenter()
maven { url "https://jitpack.io" }
mavenCentral()
}
}
Now you need to include your dependency in the project like we do with other dependencies as well
implementation 'com.demo.android:qrcodescanner:1.0.0'
keep in mind format should groupdId:artifactId:version
That's it.
References :
Publish Library
Local Maven
Simply adding #aar at the end of the dependency is what worked for me.
dependencies {
implementation 'org.videolan.vlc:libvlc:3.0.13#aar'
}
Related
I have 2 different project build on mvn. I am trying to replace to Gradle.
Project 1 is an SDK, and project 2 is using that sdk (example).
In the time of maven it creates artifact using mvn install which adds the whole project into local repository.
I like to work in gradle like that. I like project 1 build.gradle need to post it as a gradle local repository and then example project need to use it.
In maven we do mvn install which adds a project artifact into .m2 folder but how to do in gradle so what i can add a project artefact's into the local repository.
Any way that I can do so?
sdk/build.gradle:
apply plugin: "maven"
group = "foo"
version = "1.0"
example/build.gradle:
repositories {
mavenLocal()
}
dependencies {
compile "foo:sdk:1.0"
}
$sdk> gradle install
$example> gradle build
You may be looking for:
gradle publishToMavenLocal
build.gradle:
plugins {
// other plugins
id 'maven-publish'
}
publishing {
publications {
maven(MavenPublication) {
from components.java
}
}
}
See: Maven Publish Plugin
Check out Gradle's documentation on multi-project builds.
Here's an example, with some extra dependencies. Just call gradle install in the root folder, and all will be built and put to your local repo.
Folder structure:
root
+--> build.gradle
+--> settings.gradle
+--> sdk
| +--> build.gradle
+--> example
+--> build.gradle
root/build.gradle:
allprojects {
apply plugin: 'java'
apply plugin: 'maven'
group = 'myGroup'
version = '0.1-SNAPSHOT'
}
root/settings.gradle:
include 'sdk'
include 'example'
root/sdk/build.gradle:
dependencies {
// just an example external dep.
compile group:'commons-lang', name:'commons-lang', version:'2.3'
}
root/example/build.gradle:
dependencies {
compile project(':sdk')
compile group:'log4j', name:'log4j', version:'1.2.16'
}
You need to publish your own library to your local repository. You can do that in the following way:
Add maven-publish plugin:
plugins {
// your other plugins come here...
id 'maven-publish'
}
Add the publishing section to your build file:
publishing {
publications {
myCoolLibrary(MavenPublication) {
from components.java
}
}
}
Run gradle build publishToMavenLocal
Find more details in the documentation.
In my gradle project i have two subprojects, one called api and the other core:
api.gradle
plugins {
id 'java-library'
}
repositories {
maven { url 'https://repo.spongepowered.org/repository/maven-public/' }
}
dependencies {
api('org.spongepowered:spongeapi:8.0.0')
}
core.gradle
dependencies {
implementation(project(':api'))
}
The problem is that when I try to compile the core subproject I get the following error:
> Could not find org.spongepowered:spongeapi:8.0.0-SNAPSHOT.
Adding the spongepowered repository in core.gradle works, but I wanted to know if there is a way to also add the repository transitive to reduce boilerplate.
Repositories used by every subproject (in your case - api & core) can be declared in the settings.gradle file at the root of the project:
settings.gradle
dependencyResolutionManagement {
repositories {
mavenCentral()
maven { url 'https://repo.spongepowered.org/repository/maven-public/' }
}
}
I am new to both Gradle and JavaFX. I have added the JavaFX plugin to my build.gradle following this and this. However, my main class Library.java is not able to detect the Application class of JavaFX when I am trying to extend it.
build.gradle
plugins {
// Apply the java-library plugin to add support for Java Library
id 'java-library'
id 'application'
id 'org.openjfx.javafxplugin' version '0.0.8'
}
repositories {
// Use jcenter for resolving dependencies.
// You can declare any Maven/Ivy/file repository here.
jcenter()
mavenCentral()
}
dependencies {
// This dependency is exported to consumers, that is to say found on their compile classpath.
api 'org.apache.commons:commons-math3:3.6.1'
// This dependency is used internally, and not exposed to consumers on their own compile classpath.
implementation 'com.google.guava:guava:28.0-jre'
// Use JUnit test framework
testImplementation 'junit:junit:4.12'
}
jar {
manifest {
attributes 'Main-Class': 'Chess.Library'
}
}
mainClassName = 'Chess.Library'
Screenshot of Library Class
There's no Application from javafx package at all. What am I missing here?
I am using Spring Tool Suite 4.0 as my IDE with Buildship Gradle plugin if that's of any help. I am also running on Oracle Java 13
Edit 1:
I have added the changes suggested and this is how my build.gradle now looks
plugins {
// Apply the java-library plugin to add support for Java Library
id 'java-library'
id 'application'
id 'org.openjfx.javafxplugin' version '0.0.8'
}
repositories {
// Use jcenter for resolving dependencies.
// You can declare any Maven/Ivy/file repository here.
jcenter()
mavenCentral()
}
dependencies {
// This dependency is exported to consumers, that is to say found on their compile classpath.
api 'org.apache.commons:commons-math3:3.6.1'
// This dependency is used internally, and not exposed to consumers on their own compile classpath.
implementation 'com.google.guava:guava:28.0-jre'
// Use JUnit test framework
testImplementation 'junit:junit:4.12'
}
jar {
manifest {
attributes 'Main-Class': 'Chess.Library'
}
}
javafx {
version = "13"
modules = [ 'javafx.controls' ]
}
mainClassName = 'Chess.Library'
But the problem is still there
I also checked my Project and External Dependencies, there are all the libraries except for javafx
I fixed the issue myself although not sure what was causing it, but my project's buildpath had an unbounded Java 13. Fixing that and restarting the IDE took care of it
I am trying to write a React Native version of this module https://github.com/paypal/PayPal-Cordova-Plugin
It is deprecated, but until we can transition to Braintree, we need the functionality for an existing app.
It has a dependency:
repositories{
mavenCentral()
}
dependencies {
compile('com.paypal.sdk:paypal-android-sdk:2.16.0') {
exclude group: 'io.card'
}
}
I would think that I should add this to the build.gradle file for the React Native app, but when I go there, I see this:
dependencies {
classpath("com.android.tools.build:gradle:3.4.1")
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
So it seems like I should have a build.gradle file in my module directory, which I do - the same as the one above (com.paypal.sdk...)
However, it doesn't seem to be registering.
Is there a way to indicate to download this dependency? I know in iOS there is pod install - is there an equivalent method in Android?
How do I install this dependency?
EDIT: My newest plugin build.gradle is this, and it still throws an error due to the library being missing:
buildscript {
repositories {
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:1.3.1'
}
}
repositories {
mavenCentral()
}
dependencies {
compile 'com.paypal.sdk:paypal-android-sdk:2.16.0'
compile 'com.facebook.react:react-native:+'
}
I am trying to use code from this project: https://github.com/gabrielemariotti/cardslib, and I am trying to do this with intelij. In the instructions provided with the library it simply says to add this to build.gradle file:
dependencies {
compile 'com.github.gabrielemariotti.cards:library:1.3.0'
}
however when I add this and try to use code from the project intelij gives errors such as unable to resolve symbol, etc. So I am wondering what are the other steps needed to use code from this project that must be done using intelij. Any help is appreciated.
My build.gradle file currently looks like this:
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath 'com.android.tools.build:gradle:0.6+'
}
}
apply plugin: 'android'
repositories {
mavenCentral()
}
dependencies {
compile files('libs/android-support-v4.jar')
compile files('libs/GoogleAdMobAds.jar')
compile files('libs/libGoogleAnalyticsV2')
compile files('libs/amazon-ads-5.1.10.jar')
compile project('libraries/cardslib/library')
}
android {
compileSdkVersion 17
buildToolsVersion "17.0.0"
defaultConfig {
minSdkVersion 14
targetSdkVersion 16
}
}
dependencies {
// Cards Library
compile 'com.github.gabrielemariotti.cards:library:0.6.0'
compile project(':libraries:cardslib:library')
}
The documents here are also helpful to new Maven users.
Download and Install Maven - Download the latest version of Maven and install it
Quick Start - Get started building the project quickly
Use Maven - Learn how to use Maven on your own project
Refer this the below link to get much more details...
http://maven.apache.org/run-maven/
You need to add the maven central repository to your build file.
The simplest way is to just put this in your build.gradle directly under apply plugin: 'android':
repositories {
mavenCentral()
}
Resync your IDE with the gradle file after doing so.
It should resolve the dependency like any other maven central dependency (e.g. ABS).
If you are using sources (git repo cloned) at rootProject/libraries/cardslib, then add its library in rootProject/settings.gradle:
include ':appModule', ':libraries:cardslib:library'
and then in rootProject/appModule/build.gradle:
dependencies {
compile project(':libraries:cardslib:library')
}
Or, if you use maven, then just do this in rootProject/appModule/build.gradle:
dependencies {
compile 'com.github.gabrielemariotti.cards:library:1.3.0'
}
so the library's jar/aar will be downloaded in ~/.gradle/caches/modules-2/... and be compiled.
Pick one of above, don't do both.