Create external link in Javadoc using Gradle in Android Studio - android-studio

I have created a Gradle task that generates a javadoc using Doclava:
My code (the arguments of some of my methods) references classes defined in Android. When Javadoc is built, these references link correctly to the Android online reference. However, when I use the #ling tag to link to Android references, it does not work and I get something like:
configurations {
jaxDoclet
classpaths
}
dependencies {
// For Doclava JavaDoc
jaxDoclet("com.google.doclava:doclava:1.0.6")
classpaths files('build/intermediates/classes/debug')
classpaths project.files(android.getBootClasspath().join(File.pathSeparator))
}
task javadoc(type: Javadoc) {
source = android.sourceSets.main.allJava
source += fileTree("build/generated/source/r/debug")
title = null
options {
docletpath = configurations.jaxDoclet.files.asType(List)
doclet "com.google.doclava.Doclava"
bootClasspath new File(System.getenv('JAVA_HOME') + "/jre/lib/rt.jar")
classpath += configurations.classpaths.files.asType(List)
addStringOption "public"
addStringOption "federate android", "http://d.android.com/reference"
addStringOption "federationxml android", "http://doclava.googlecode.com/svn/static/api/android-10.xml"
}
}
warning 101: Unresolved link/see tag "Runnable" in com....
In similar questions in SO, it was advised to use -link and -linkoffline flags. However, when I do that I get:
javadoc: error - invalid flag: -linkoffline
I am using Android Studio 1.5.1 and Gradle 2.11.
Update
It seems that Doclava may not support -link and -linksoffline according to these tickets. If I use the default doclet, links work correctly.

Related

Kotlin / Gradle DSL integration to manage dependency version variables

Kotlin / Gradle DSL integration to manage dependency version variables
My question is about the best way to manage dependency version variables in IntelliJ Idea / Android Studio using Gradle
Kotlin DSL
The secondary purpose is to have the IDE perform version upgrades upon clicking the suggestion to change to newer
version automatically instead of manually editing the versioning file entry.
the simple way
definition
build.gradle.kts
plugins {
application
kotlin("jvm") version "1.7.10"
}
dependencies {
implementation("io.ktor:ktor-server-core-jvm:2.1.1")
}
Comments
This is working but "clumsy" and does not comply to single source of truth (SSOT)
I have seen several ways that attempt having a SSOT for the dependency versions
by Project
Definition
gradle.properties
ktor_version = 2.1.0
kotlin_version = 1.7.10
build.gradle.kts
val ktor_version: String by project // NOTE the complaint Property name 'ktor_version' should not contain underscores
val kotlin_version: String by project
plugins {
application
kotlin("jvm") version "1.7.10" // NOTE you cannot replace this with the variable!
// 'val kotlin_version: String' can't be called in this context by implicit receiver. Use the explicit one if necessary
}
dependencies {
implementation("io.ktor:ktor-server-core-jvm:$ktor_version")
}
Comments
This does not update the suggested version numbers via "Project Structure/Suggestions" in AS/IJ
my inline NOTES indicate several issues with this method!
by buildSrc java Module
Definition
object Ktor {
private const val ktorVersion = "2.0.0"
const val core = "io.ktor:ktor-client-core:${ktorVersion}"
const val android = "io.ktor:ktor-client-android:${ktorVersion}"
}
implementation in build.gradle.kts
implementation(Ktor.android)
Comments
This does not update the suggested version numbers via "Project Structure/Suggestions" in AS/IJ, is seemed to
be totally de-coupled, and it is a nightmare to manually find and update the versions manually to the latest!
However: doing it by buildSrc java Module makes it much easier to re-use in other projects
by Gradle Version Catalogs
Definition
libs.versions.toml // in the gradle directory next to wrapper
[versions]
plugin-kotlin = "1.7.10"
ktor = "2.1.0"
[libraries]
plugin-kotlin = { module = "org.jetbrains.kotlin:kotlin-gradle-plugin", version.ref = "plugin-kotlin" }
ktor-client-core = { module = "io.ktor:ktor-client-core", version.ref = "ktor" }
[bundles]
plugins = ["plugin-android", "plugin-kotlin", "plugin-kotlin-serialization", "plugin-sqldelight"]
implementation in build.gradle.kts(project)
buildscript {
repositories {
gradlePluginPortal()
google()
mavenCentral()
}
dependencies {
classpath(libs.bundles.plugins)
}
}
implementation in build.gradle.kts(shared)
sourceSets {
val commonMain by getting {
dependencies {
implementation(libs.ktor.client.core)
}
}
}
Comments
This is by far the favorite of mine, the reason is clear, it allows SSOT, and it allows grouping/bundling to make
"sets" that is more understandable later on
However!
This does not update the suggested version numbers via "Project Structure/Suggestions" in AS/IJ
it is a nightmare to manually find and update the versions manually to the latest!
Main question
Is there a better way of managing dependency versions?
Is there a way that works inside the IDE AS/IJ suggestions to update the versions correctly at the definition
location?

Choosing different libraries for compilation and runtime

I have two libraries with same classes defined in each one. However they have some different contents (methods/constants).
For example:
Library 1:
package com.test.package;
Class A {
// only method signatures
public void methodA() {
}
public void methodB() {
}
}
Library 2:
package com.test.package;
Class A {
public void methodA() {
// some logic that MUST be executed to provide backward compatibility
}
}
My application uses Library 1 and Library 2 and run in devices which have com.test.package.ClassA, but com.test.package.ClassA.methodB() will only exist in newer releases in framework. Said that, I need the Library 1 to be used to compile my application and the Library 2 to execute a different implementation of methodA().
I have tried to do this in Android Studio using .jar and .aar libraries format, but none of them worked for me.
Is it possible to set this configuration in an Android Studio project?
I am building both Library 1 and 2, and I cannot add methodB() in Library 2.
For a simple Java application, you can do this by unlinking the compile and runtime configurations. I set up an example repository here.
The idea is shown in this commit, but can be described as manually resetting the runtime configuration so that it doesn't include the contents of the compile configuration. After doing so, you can just include your runtime library variation in the runtime configuration.
The application's build.gradle becomes something like:
apply plugin: 'application'
mainClassName = 'my.package.MyAppClass'
configurations.runtime.extendsFrom = [] // Reset runtime configuration
dependencies {
compile 'my.group:my.artifact:2.0' // Library 1, with the new method
runtime 'my.group:my.artifact:1.0' // Library 2, without the method
}
For Android, this can be a little more complicated. The problem is that there's no runtime configuration for Android (because you don't execute it on your computer, unless you're using Robolectric or something similar).
I think there are a few workarounds you can probably use, but one initial suggestion would be to create a wrapper library that abstracts away the dependency on the other libraries. This wrapper library you can compile with the newest library version (Library 1, with the new method). You could then include the wrapper library in the Android app while setting it as a non-transitive dependency and including the other library version:
dependencies {
compile 'my.group:my.wrapped.artifact:0.1' {
transitive = false // Don't include dependencies of the wrapper
// i.e., don't include version 2.0 of the lib.
}
compile 'my.group:my.artifact:1.0'
}
This should work because by setting the dependency as non-transitive Gradle doesn't recursively include the dependencies of the wrapper library, so the version used to compile the wrapper isn't included (in theory) in the APK. You can therefore add the old version without causing a conflict.
An example is set up in the same repository, under the Android branch. Firstly, two Java libraries are created. Then an Android library is created to wrap around the compile-time library. An example activity is created to show how using the wrapper library uses the compile-time library. Then, the latest commit shows how the app is configured to use the wrapper library (which compiles with the newest library) but forces the old library to be included instead in the runtime.
Hope this helps =)

Kotlin unresolved reference linkedListOf

Following this post http://obviam.net/index.php/libgdx-and-kotlin/ I
created a project, and edited using Atom. It compiles, and runs on an android device. I want to convert to AndroidStudio for better tooling.
I'm using AndroidStudio 1.5.1, and it says I have the latest version of the kotlin plugin. I created a new project using the LibGDX setup program, imported into AdroidStudio, converted the main class to kotlin, everything works. Then I pasted in my existing my code, and when I build, this line:
val bullets:MutableList<NewBullet> = linkedListOf()
gets this error:
Error:(19, 42) Unresolved reference: linkedListOf
When I select Tools -> Kotlin -> Configure it says 'All modules with Kotlin files are configured'.
I've also tried importing the existing project into AndroidStudio, and the result is the same issue.
As said in the change log of Kotlin 1.0 RC, linkedListOf has been deprecated and is not available now. The article you referenced uses Kotlin 1.0 Beta, which is older.
To create a LinkedList<T> from varargs, you can pass a listOf(...) to the constructor:
val bullets: MutableList<SomeType> = LinkedList(listOf(item1, item2))
or write your own linkedListOf:
fun <T> linkedListOf(vararg items: T) = LinkedList<T>().apply {
for (i in items) { add(i) }
}

Error with Nullable annotation when generating Javadoc using doclava

I am trying to generate a Javadoc for an Android Library using Doclava in Android Studio. The source code uses "Nullable" tag at some point and this causes a crash while generating the javadoc:
In doclet class com.google.doclava.Doclava, method start has thrown an exception java.lang.reflect.InvocationTargetException
com.sun.tools.javac.code.Symbol$CompletionFailure: class file for javax.annotation.Nullable not found
Can I somehow overcome this?
I had to include in Javadoc's classpath, the findbugs:jsr305 library.
So, in my Gradle configuration, I added:
dependencies {
// For Doclava JavaDoc
jaxDoclet("com.google.doclava:doclava:1.0.6")
classpaths files('build/intermediates/classes/release')
classpaths 'com.google.code.findbugs:jsr305:3.0.1'
}
task javadoc(type: Javadoc) {
//.... the rest of the configuration
options {
classpath += configurations.classpaths.files.asType(List)
//.... the rest of the configuration
}
}
For this exception, check here: https://code.google.com/p/android/issues/detail?id=1261
Just add -XDignore.symbol.file to the end of the command, and it may remove this exception.

How can I specify a Groovy CompilerConfig using Gradle?

I have a Groovy project, where I would like to enable this CompilerConfig:
withConfig(configuration) {
ast(groovy.transform.CompileStatic)
ast(groovy.transform.TypeChecked)
}
How can I enable this using Gradle?
Beginning from Gradle 2.1 it is possible, see the corresponding release notes.
This is especially useful for working with Groovy on Android, see this presentation. E.g. you could add the #CompileStatic to each class with the following code:
File build.gradle
compileGroovy {
groovyOptions.configurationScript = file("gradle/config.groovy")
}
File gradle/config.groovy
withConfig(configuration) {
ast(groovy.transform.CompileStatic)
}
For more options, see the GroovyCompileOptions and Groovy Customizer Builder.
Gradle's GroovyCompile task doesn't currently support passing a CompilerConfiguration instance or --configscript option. See http://forums.gradle.org/gradle/topics/ability_to_specify_a_compilerconfiguration_instance_for_groovycompile_task for a related discussion.

Resources