configurations.compile is empty - android

I have been using the following task to copy libraries:
task copyLibs(type: Copy, dependsOn: 'cleanLibs') {
from configurations.compile
into 'libs'
}
But with newer version of gradle, the compile configuration was replaced with implementation. I think this is why the configurations.compile list is now empty. I've tried referencing configuration.implementation and configuration.implementation.resolvedConfiguration directly, but this produces the following error:
Resolving configuration 'implementation' directly is not allowed
If I try to use configurations.compile.resolvedConfiguration I get org.gradle.api.internal.artifacts.ivyservice.ErrorHandlingConfigurationResolver$ErrorHandlingResolvedConfiguration#5bb68e71.
How can I achieve the expected result (copy all dependencies to 'libs' folder)?

Try configurations.compileClasspath instead.
This worked for me with Gradle 4.5.1:
task listJars {
doLast {
configurations.compileClasspath.each { println it }
}
}

Related

How can I set gradle resolutionStrategy for only the release build?

I'm developing an android app where I want the release build to fail if there is a dependency version conflict. If I want to enable it for all builds, I can do this:
configurations.all {
resolutionStrategy {
failOnVersionConflict()
}
}
However I don't want to enable it for debug builds. I can't find any documentation on how to do that. I've tried:
configurations.each {
if (it.name.startsWith("release")) {
it.resolutionStrategy {
failOnVersionConflict()
}
}
}
But it doesn't apply. I've even tried what I thought would be the equivalent of the first example - but this has no effect:
configurations.each {
it.resolutionStrategy {
failOnVersionConflict()
}
}
I'm simply switching .all for .each here, but failOnVersionConflict doesn't apply even though the code is executed.
What am I doing wrong?
It should work in the following way:
apply plugin: 'java'
configurations.compile.resolutionStrategy {
failOnVersionConflict()
}
repositories {
mavenCentral()
}
dependencies {
compile 'com.google.guava:guava:23.0'
compile 'com.google.guava:guava:22.0'
}
task deps(type: Copy) {
from configurations.compile
into('deps')
}
When you run gradle deps then it should fail with version conflict. If you comment out configuration block guava version 23.0 will be copied.

Gradle 3.0 Upgrade Causes androidJavadocs Error

I updated the following:
//gradle
classpath 'com.android.tools.build:gradle:3.0.0-beta6'
// library dependencies
implementation "com.android.support:appcompat-v7:26.1.0"
implementation "com.google.code.gson:gson:2.7"
implementation "com.google.android.gms:play-services-location:11.2.2"
I am now getting the following exception kinds of exceptions for the gradle task androidJavadocs.
error: package com.google.android.gms.security does not exist
error: package com.google.gson does not exist
error: cannot find symbol class NonNull
Here is the gradle task that used to allow me to package up the javadocs but this no longer suffices:
libraryVariants.all { variant ->
if (variant.name == 'release') {
task docs(type: Javadoc) {
println 'docs task'
source = variant.javaCompiler.source
classpath += files(((Object) android.bootClasspath.join(File.pathSeparator)))
classpath += files(variant.javaCompiler.classpath.files)
}
}
}
I have tried lots of different combinations of gradle tasks and workarounds that I've found searching around but nothing works and I continue to get these errors. I have tried cleaning the project and invalidating the cache. Any ideas?
Adding the following to my upload-archives.gradle file fixed the problem:
task androidJavadocs(type: Javadoc) {
source = android.sourceSets.main.java.srcDirs
// this is new
android.libraryVariants.all { variant ->
if (variant.name == 'release') {
owner.classpath += variant.javaCompiler.classpath
}
}
// end of new
classpath += project.files(android.getBootClasspath().join(File.pathSeparator))
}

How do I build jar file in Android studio using gradle?

I want to build dependency.
I have gcm-src.jar file.and i want to show compile files('libs/gcm-src.jar') in app build.gradle.
Use this in your gradle file
// For making jar
task clearJar(type: Delete) {
delete 'build/libs/nameOfYourJar.jar'
}
task makeJar(type: Copy) {
from('build/intermediates/bundles/release/')
into('release/')
include('classes.jar')
rename('classes.jar', 'nameOfYourJar.jar')
}
makeJar.dependsOn(clearJar, build)

How to generate javadoc for android library when it has dependencies which are also aar libraries?

I have android library project which depends on other android library projects. I need to generate javadoc for library but it fails because gradle puts to javadoc classpath path to .aar locations but javadoc expects .jar files.
simplified gradle file:
android {
compileSdkVersion 23
buildToolsVersion "23.0.2"
configurations {
javadocDeps
}
defaultConfig {
minSdkVersion 7
targetSdkVersion 23
versionCode 1
versionName "0.1.0"
}
}
dependencies {
compile 'com.android.support:support-v4:23.2.0'
compile 'com.android.support:appcompat-v7:23.2.0'
compile 'com.nineoldandroids:library:2.4.0'
compile 'com.annimon:stream:1.0.7'
javadocDeps 'com.android.support:support-annotations:23.2.0'
javadocDeps 'com.nineoldandroids:library:2.4.0'
javadocDeps 'com.android.support:support-v4:23.2.0'
}
task sourcesJar(type: Jar) {
from android.sourceSets.main.java.srcDirs
classifier = 'sources'
}
task javadoc(type: Javadoc, dependsOn: explodeAars) {
source = android.sourceSets.main.java.srcDirs
classpath += project.files(android.getBootClasspath().join(File.pathSeparator))
classpath += configurations.javadocDeps
}
task javadocJar(type: Jar, dependsOn: javadoc) {
classifier = 'javadoc'
from javadoc.destinationDir
}
artifacts {
archives javadocJar
archives sourcesJar
}
3 solutions possible:
1) somehow to add to the classpath path classes.jar from every aar library it depends build/intermidiates/exploded-aar/library/version/jars/classes.jar
I don't know how to include these paths in javadoc task.
2) manually unpack classes.jar from aar file and add them to classpath of javadoc task
3) very dirty hack - hardcoded paths to library - but I think this is so WRONG.
How to achieve 1 or 2 with gradle dsl?
I managed to automate the solution of Guillaume Perrot by extracting the classes.jar contained in each AAR file, and adding it to the classpath of the javadoc task.
It seems to work for AAR dependencies and AAR modules on Android Studio 2.3 and Gradle 3.3
import java.nio.file.Files
import java.nio.file.Paths
import java.io.FileOutputStream
import java.util.zip.ZipFile
task javadoc(type: Javadoc) {
source = android.sourceSets.main.java.srcDirs
classpath += configurations.compile
classpath += configurations.provided
afterEvaluate {
// Wait after evaluation to add the android classpath
// to avoid "buildToolsVersion is not specified" error
classpath += files(android.getBootClasspath())
// Process AAR dependencies
def aarDependencies = classpath.filter { it.name.endsWith('.aar') }
classpath -= aarDependencies
aarDependencies.each { aar ->
// Extract classes.jar from the AAR dependency, and add it to the javadoc classpath
def outputPath = "$buildDir/tmp/aarJar/${aar.name.replace('.aar', '.jar')}"
classpath += files(outputPath)
// Use a task so the actual extraction only happens before the javadoc task is run
dependsOn task(name: "extract ${aar.name}").doLast {
extractEntry(aar, 'classes.jar', outputPath)
}
}
}
}
// Utility method to extract only one entry in a zip file
private def extractEntry(archive, entryPath, outputPath) {
if (!archive.exists()) {
throw new GradleException("archive $archive not found")
}
def zip = new ZipFile(archive)
zip.entries().each {
if (it.name == entryPath) {
def path = Paths.get(outputPath)
if (!Files.exists(path)) {
Files.createDirectories(path.getParent())
Files.copy(zip.getInputStream(it), path)
}
}
}
zip.close()
}
The solution from #rve is now broken on Android Studio 2.3 / Gradle 3.3 as the exploded-aar no longer exists (with no alternative inside the build directory).
If the aar you depend on is not a module in your project, you will need first to extract the classes.jar before referencing it in the classpath (basically re-create intermediates/exploded-aar manually).
If the aar you depend on is just another module in your project you can also make your javadoc task depends on the compile task of that module and reference the intermediates/classes/release of that module (if you make javadoc depends on assembleRelease for example). An example of that workaround: https://github.com/Microsoft/mobile-center-sdk-android/pull/345/files
I really wish someone comes up with a better solution though.
This only works for Android Studio older than 2.3 and/or Gradle older than 3.3
To add the JARs from the AARs you can add the following doFirst to the javadoc task:
task javadoc(type: Javadoc) {
source = android.sourceSets.main.java.srcDirs
}
.doFirst {
classpath += fileTree(dir: "$buildDir/intermediates/exploded-aar/", include:"**/classes.jar")
}
It will add all .jar files from all the AARs to the javadoc classpath. (option 1 from your proposed solutions)
This is how I solved this issue, using zipTree. Configuration: Gradle 4.10, Gradle Plugin: 3.3.2, Android Studio: 3.4.
task javadoc(type: Javadoc) {
doFirst {
configurations.implementation
.filter { it.name.endsWith('.aar') }
.each { aar ->
copy {
from zipTree(aar)
include "**/classes.jar"
into "$buildDir/tmp/aarsToJars/${aar.name.replace('.aar', '')}/"
}
}
}
configurations.implementation.setCanBeResolved(true)
source = android.sourceSets.main.java.srcDirs
classpath += project.files(android.getBootClasspath().join(File.pathSeparator))
classpath += configurations.implementation
classpath += fileTree(dir: "$buildDir/tmp/aarsToJars/")
destinationDir = file("${project.buildDir}/outputs/javadoc/")
failOnError false
exclude '**/BuildConfig.java'
exclude '**/R.java'
}
I am running the new Android Studio 3.0-beta7, and tried to use #nicopico's answer, but it failed with a number of different errors, so here's an adaptation of it that doesn't rely on the non-existent java.nio utilities.
task javadoc(type: Javadoc) {
failOnError false
source = android.sourceSets.main.java.srcDirs
// Also add the generated R class to avoid errors...
// TODO: debug is hard-coded
source += "$buildDir/generated/source/r/debug/"
// ... but exclude the R classes from the docs
excludes += "**/R.java"
// TODO: "compile" is deprecated in Gradle 4.1,
// but "implementation" and "api" are not resolvable :(
classpath += configurations.compile
afterEvaluate {
// Wait after evaluation to add the android classpath
// to avoid "buildToolsVersion is not specified" error
classpath += files(android.getBootClasspath())
// Process AAR dependencies
def aarDependencies = classpath.filter { it.name.endsWith('.aar') }
classpath -= aarDependencies
aarDependencies.each { aar ->
System.out.println("Adding classpath for aar: " + aar.name)
// Extract classes.jar from the AAR dependency, and add it to the javadoc classpath
def outputPath = "$buildDir/tmp/exploded-aar/${aar.name.replace('.aar', '.jar')}"
classpath += files(outputPath)
// Use a task so the actual extraction only happens before the javadoc task is run
dependsOn task(name: "extract ${aar.name}").doLast {
extractEntry(aar, 'classes.jar', outputPath)
}
}
}
}
// Utility method to extract only one entry in a zip file
private def extractEntry(archive, entryPath, outputPath) {
if (!archive.exists()) {
throw new GradleException("archive $archive not found")
}
def zip = new java.util.zip.ZipFile(archive)
zip.entries().each {
if (it.name == entryPath) {
def path = new File(outputPath)
if (!path.exists()) {
path.getParentFile().mkdirs()
// Surely there's a simpler is->os utility except
// the one in java.nio.Files? Ah well...
def buf = new byte[1024]
def is = zip.getInputStream(it)
def os = new FileOutputStream(path)
def len
while ((len = is.read(buf)) != -1) {
os.write(buf, 0, len)
}
os.close()
}
}
}
zip.close()
}
It bothers me that we need all this code to produce a freaking javadoc for a library, but at least I got this working. However, I do need to find a workaround for configuration.api and configuration.implementation not being resolvable.
All of the solutions listed here are out of date if you are developing an Android app/library using Kotlin. To generate javadocs as well as documentation in several other formats, use KDoc and Dokka:
https://kotlinlang.org/docs/kotlin-doc.html
https://kotlin.github.io/dokka/1.5.0/
https://github.com/Kotlin/dokka
I posted a solution for this problem at Android AAR depending on AAR fails with javadoc generation. I think Johann comment that the listed solutions are out of date is probably correct, but mike192 solution looks pretty good, although I think it might have a problem handling androidx dependencies. I haven't tried KDoc and Dokka yet, but in looking at the documentation, that looks promising. Hopefully it works for android java libraries. The android studio's built-in javadoc tool (2021.2.1) has issues handling that module type; hence the need to build a custom javadoc task to work around those issues.

Gradle: DefaultAndroidSourceDirectorySet to File using toString() method has been deprecated

I want to update the Gradle plug-in of an Android library project. The new version is 0.10.4. The Gradle wrapper is at 1.10. The following warning appears when I run ./gradlew install on the project.
Converting class com.android.build.gradle.internal.api. \
DefaultAndroidSourceDirectorySet to File using toString() method has
been deprecated and is scheduled to be removed in Gradle 2.0.
Please use java.io.File, java.lang.String, java.net.URL, or java.net.URI instead.
I am not sure but the marked lines should the cause:
// build.gradle
task androidJavadocs(type: Javadoc) {
source = android.sourceSets.main.java // <----
}
task androidJavadocsJar(type: Jar) {
classifier = 'javadoc'
from androidJavadocs.destinationDir
}
task androidSourcesJar(type: Jar) {
classifier = 'sources'
from android.sourceSets.main.java // <----
}
How can I rewrite the code to get rid of the warning?
android.sourceSets.main.java doesn't have the type you expect. You're passing it to something that expects a File[], but it actually has the type com.android.build.gradle.internal.api.DefaultAndroidSourceDirectorySet. If you look at the API for Android sourceSets at you'll find that there's a sourceDirs method that returns what you want. So set up your tasks like this:
task androidJavadocs(type: Javadoc) {
source = android.sourceSets.main.java.srcDirs
}

Categories

Resources