When I build an app with a *.aar file instead of the module with Gradle 4.x and following the docu concerning implements and api, I expect using api the included aar file has all dependencies included, but it hasn't.
When you do
git clone https://github.com/hannesa2/aar_dependency
./gradlew clean assembleDebug
means
dependencies {
api project(':mylibrary')
it works properly.
But when I use insted of lib-module the previous generated *.aar file as dependency
dependencies {
api 'com.example.my.mylibrary:mylibrary-debug#aar'
(in demo app just do)
git checkout with_aar
./gradlew clean assembleDebug
I run into this
Task :app:transformClassesWithDesugarForDebug
Exception in thread "main" java.lang.TypeNotPresentException: Type io.reactivex.ObservableTransformer not present
at sun.invoke.util.BytecodeDescriptor.parseSig(BytecodeDescriptor.java:85)
at sun.invoke.util.BytecodeDescriptor.parseMethod(BytecodeDescriptor.java:63)
at sun.invoke.util.BytecodeDescriptor.parseMethod(BytecodeDescriptor.java:41)
at java.lang.invoke.MethodType.fromMethodDescriptorString(MethodType.java:1067)
at com.google.devtools.build.android.desugar.LambdaDesugaring$InvokedynamicRewriter.visitInvokeDynamicInsn(LambdaDesugaring.java:399)
at org.objectweb.asm.MethodVisitor.visitInvokeDynamicInsn(Unknown Source)
at org.objectweb.asm.MethodVisitor.visitInvokeDynamicInsn(Unknown Source)
Because I ordinary run into this with uploading the aar artifacts into our company Maven Nexus, I created this demo-repo to show exactly what's wrong. In demo app or using Maven I see the same issue.
Does someone knows what I did wrong ?
I was able to solve it. The main issue was Android O with Gradle 4.x using api
dependencies {
api 'com.squareup.okhttp3:logging-interceptor:3.4.1'
api "io.reactivex.rxjava2:rxandroid:$versions.libs.rxAndroid"
Most answers are concerning something like this
publishing {
publications {
mipartner(MavenPublication) {
groupId '...'
artifactId '..'
version 1.0
artifact "$buildDir/outputs/aar/myLib-release.aar"
//generate pom nodes for dependencies
pom.withXml {
def dependenciesNode = asNode().appendNode('dependencies')
configurations.compile.allDependencies.each { dependency ->
def dependencyNode = dependenciesNode.appendNode('dependency')
dependencyNode.appendNode('groupId', dependency.group)
dependencyNode.appendNode('artifactId', dependency.name)
dependencyNode.appendNode('version', dependency.version)
}
}
}
}
repositories{
maven {
url "https://some.url.com"
}
}
}
but here in the resulting *.pom there are no dependencies included, after change this line to api the dependencies are included in deployed pom !
configurations.api.allDependencies.each { dependency ->
after this you can easily consume the aar file
dependencies {
api "com.mylib.net:mylib:1.0"
Related
I've just migrated my Android lib from JCenter to MavenCentral. The process completed successfully and I can find my lib through Sonatype Repo Search.
However, when I try to use the lib in my sample application, I get the following error:
Execution failed for task ':sample:checkDebugAarMetadata'.
> Could not resolve all files for configuration ':sample:debugRuntimeClasspath'.
> Could not find :unspecified:.
Required by:
project :sample > com.techyourchance:threadposter:1.0.0
Possible solution:
- Declare repository providing the artifact, see the documentation at https://docs.gradle.org/current/userguide/declaring_repositories.html
It looks like Gradle finds my lib (because if I change to a non-existent version, say 2.0.0, then I get completely different error), but there is some problem with the artifact.
All the source code (both the lib and the sample app) can be found here. Specifically, here is build.gradle of the lib and that's the additional Gradle script that handles publication to Sonatype.
I've already spent two hours searching for each of the above error messages on the internet, but couldn't solve this issue so far.
Skip dependencies with name 'unspecified' in your publish-maven.gradle.
withXml {
def dependenciesNode = asNode().appendNode('dependencies')
project.configurations.implementation.allDependencies.each {
if (it.name != 'unspecified') {
def dependencyNode = dependenciesNode.appendNode('dependency')
dependencyNode.appendNode('groupId', it.group)
dependencyNode.appendNode('artifactId', it.name)
dependencyNode.appendNode('version', it.version)
}
}
}
I have an application consist of multiple modules. Those modules has external dependencies like Google Maps, Glide etc. compiled with "api" on gradle. Thus i can use that dependencies in app module too. However, I started to publish those modules on some package repository like jitpack and dependencies compiled with "api" are no longer reachable in my app module. What should I do?
App --implements-> mymodule --api-> glide (It works)
App --implements-> my module published on package repository --api-> glide (I can't reach to glide in app)
Edit: The problem was, while I'm publishing my aar on maven, it does not include other dependencies into the pom file. I have solved with updating my gradle publish with this:
publications {
"${getPublicationName()}" (MavenPublication) {
groupId Config.groupId
artifactId Config.artifactId
version Config.versionName
artifact getArtifactFilePath()
pom.withXml {
def dependencies = asNode().appendNode('dependencies')
configurations.getByName("${getPublicationName()}CompileClasspath").getResolvedConfiguration().getFirstLevelModuleDependencies().each {
def dependency = dependencies.appendNode('dependency')
dependency.appendNode('groupId', it.moduleGroup)
dependency.appendNode('artifactId', it.moduleName)
dependency.appendNode('version', it.moduleVersion)
}
}
}
}
I am using maven-publish plugin in gradle to publish artifacts. I need to generate a POM file that contains dependencies so that my consumers can fetch the needed dependencies.
Since maven-publish does not by default contains dependencies onto POM file, I had to use
pom.withXml {
def dependenciesNode = asNode().appendNode('dependencies')
configurations.compile.allDependencies.each {
def dependencyNode = dependenciesNode.appendNode('dependency')
dependencyNode.appendNode('groupId', it.group)
dependencyNode.appendNode('artifactId', it.name)
dependencyNode.appendNode('version', it.version)
dependencyNode.appendNode('scope', 'compile')
}
}
It was all working fine to me until I swapped keyword compile to api or Implementation.
the published POM does not contain any dependencies uses keyword api or Implementation. I had to use compile to make it included in POM file, am I missing anything here?
After couple of hours searching online, I just realized that the property you include POM file is changed as well.
It now become
//for implementation dependencies
configurations.implementation.allDependencies.each { ... }
//for api dependencies
configurations.api.allDependencies.each { ... }
However,
configurations.implementation.allDependencies.each { ... }
seems includes api dependencies in the POM file already.
you can simply skip the scope part, you hardly come across maven dependencies with scopes. ':D
When I build an app with a *.aar file instead of the module with Gradle 4.x and following the docu concerning implements and api, I expect using api the included aar file has all dependencies included, but it hasn't.
When you do
git clone https://github.com/hannesa2/aar_dependency
./gradlew clean assembleDebug
means
dependencies {
api project(':mylibrary')
it works properly.
But when I use insted of lib-module the previous generated *.aar file as dependency
dependencies {
api 'com.example.my.mylibrary:mylibrary-debug#aar'
(in demo app just do)
git checkout with_aar
./gradlew clean assembleDebug
I run into this
Task :app:transformClassesWithDesugarForDebug
Exception in thread "main" java.lang.TypeNotPresentException: Type io.reactivex.ObservableTransformer not present
at sun.invoke.util.BytecodeDescriptor.parseSig(BytecodeDescriptor.java:85)
at sun.invoke.util.BytecodeDescriptor.parseMethod(BytecodeDescriptor.java:63)
at sun.invoke.util.BytecodeDescriptor.parseMethod(BytecodeDescriptor.java:41)
at java.lang.invoke.MethodType.fromMethodDescriptorString(MethodType.java:1067)
at com.google.devtools.build.android.desugar.LambdaDesugaring$InvokedynamicRewriter.visitInvokeDynamicInsn(LambdaDesugaring.java:399)
at org.objectweb.asm.MethodVisitor.visitInvokeDynamicInsn(Unknown Source)
at org.objectweb.asm.MethodVisitor.visitInvokeDynamicInsn(Unknown Source)
Because I ordinary run into this with uploading the aar artifacts into our company Maven Nexus, I created this demo-repo to show exactly what's wrong. In demo app or using Maven I see the same issue.
Does someone knows what I did wrong ?
I was able to solve it. The main issue was Android O with Gradle 4.x using api
dependencies {
api 'com.squareup.okhttp3:logging-interceptor:3.4.1'
api "io.reactivex.rxjava2:rxandroid:$versions.libs.rxAndroid"
Most answers are concerning something like this
publishing {
publications {
mipartner(MavenPublication) {
groupId '...'
artifactId '..'
version 1.0
artifact "$buildDir/outputs/aar/myLib-release.aar"
//generate pom nodes for dependencies
pom.withXml {
def dependenciesNode = asNode().appendNode('dependencies')
configurations.compile.allDependencies.each { dependency ->
def dependencyNode = dependenciesNode.appendNode('dependency')
dependencyNode.appendNode('groupId', dependency.group)
dependencyNode.appendNode('artifactId', dependency.name)
dependencyNode.appendNode('version', dependency.version)
}
}
}
}
repositories{
maven {
url "https://some.url.com"
}
}
}
but here in the resulting *.pom there are no dependencies included, after change this line to api the dependencies are included in deployed pom !
configurations.api.allDependencies.each { dependency ->
after this you can easily consume the aar file
dependencies {
api "com.mylib.net:mylib:1.0"
Since I cannot use a private maven in order to share my library, I was thinking in sharing the aar and importing into another project.
The problem comes when the aar and jar files does not contain any dependency. So once I manually import the aar in android studio (using Import .JAR/.AA Package) there is no dependency, and I have to manually add all dependencies again.
I already generated a pom file through a gradle task, although I cannot find any way to manually import it on the project.
On the build.gradle file automatically generated by the "Import .JAR/.AA Package" is:
configurations.maybeCreate("default")
artifacts.add("default", file('TestSample_1.0.0.aar'))
Is there a way to add the pom/iml file too? something like:
artifacts.add("default", file('pomDependencies.xml'))
1. Publishing
In your aar project, add maven-publish plugin and add necessary plugin configuration.
apply plugin: 'com.android.library'
apply plugin: 'maven-publish'
...
dependencies {
testCompile 'junit:junit:4.12'
compile 'com.android.support:appcompat-v7:23.1.1'
compile 'com.novoda:bintray-release:0.2.7'
}
...
publishing {
publications {
maven(MavenPublication) {
groupId 'com.example' //You can either define these here or get them from project conf elsewhere
artifactId 'example'
version '0.0.1-SNAPSHOT'
artifact "$buildDir/outputs/aar/app-release.aar" //aar artifact you want to publish
//generate pom nodes for dependencies
pom.withXml {
def dependenciesNode = asNode().appendNode('dependencies')
configurations.compile.allDependencies.each { dependency ->
def dependencyNode = dependenciesNode.appendNode('dependency')
dependencyNode.appendNode('groupId', dependency.group)
dependencyNode.appendNode('artifactId', dependency.name)
dependencyNode.appendNode('version', dependency.version)
}
}
}
}
//publish to filesystem repo
repositories{
maven {
url "$buildDir/repo"
}
}
}
Few things to note:
We're using a custom maven publication, so you have to define what is being published with the artifact clause
We have to generate the pom ourselves, in the code above I'm using all compile config dependencies, you may want to make sure all the configs you care about are covered.
Running gradle publish will publish to a maven repo structure to the repo folder, which you can then consume from a different project.
2. Using published .aar
In a different android project, to use the aar published in #1:
In top level build.gradle:
allprojects {
repositories {
jcenter()
maven {
url "D:/full/path/to/repo"
}
}
}
add the path to earlier repo as a maven repository. Note that you may have to use the full path, because $buildDir has a different value for this project. In your app build.gradle:
dependencies {
...
other dependencies
...
implementation ('com.example:example:0.0.1-SNAPSHOT#aar'){transitive=true}
}
transitive=true is required for to fetch the transitive dependencies from the pom file.
Things have changed a little, here's how you do it with the latest versions of gradle
Create the package localy (aar and pom)
Modify your library build.gradle file to include
apply plugin: 'maven-publish'
android {
...
...
}
dependencies {
...
...
}
publishing {
publications {
maven(MavenPublication) {
groupId 'com.domain' //You can either define these here or get them from project conf elsewhere
artifactId 'name'
version '1.0.0'
artifact "$buildDir/outputs/aar/sdk-release.aar" //aar artifact you want to publish
//generate pom nodes for dependencies
pom.withXml {
def dependenciesNode = asNode().appendNode('dependencies')
configurations.implementation.allDependencies.each { dependency ->
if (dependency.name != 'unspecified') {
def dependencyNode = dependenciesNode.appendNode('dependency')
dependencyNode.appendNode('groupId', dependency.group)
dependencyNode.appendNode('artifactId', dependency.name)
dependencyNode.appendNode('version', dependency.version)
}
}
}
}
//publish to filesystem repo
repositories{
maven {
url "$buildDir/repo"
}
}
}
Run from terminal
./gradlew clean
./gradlew build
./gradlew --console=verbose publishToMavenLocal
The aar and pom files have been created at $HOME/.m2/repository/
How to load the library from a different project
Modify the projects's build.gradle in the following way:
allprojects {
repositories {
maven {
url "/Users/username/.m2/repository/"
}
google()
jcenter()
}
You can use $rootDir and set a relative path.
Add the library as a dependency in your app module build.gradle
implementation 'com.domain:name:1.0.0'