Error Prone
AutoDispose
is an Error-Prone
check to detect missing AutoDispose scope within defined scoped elements.
Installation¶
Below are sample configurations which pull in both the AutoDispose Error-Prone checker.
Gradle¶
Java¶
plugins {
id "java-library" // Or whatever other java plugin you're using
id "net.ltgt.errorprone" version "0.6"
}
dependencies {
errorprone "com.uber.autodispose:autodispose-error-prone:x.y.z" // where x.y.z is the latest version.
errorprone "com.google.errorprone:error_prone_core:2.3.2" // Or whatever the latest version is
}
tasks.withType(JavaCompile).configureEach {
// Only if you want to support custom types with scopes
// Below is a sample configuration which includes Conductor
def classesWithScope = [
"com.bluelinelabs.conductor.Controller"
]
options.errorprone {
check("AutoDispose", CheckSeverity.ERROR)
option("AutoDispose:TypesWithScope", classesWithScope.join(","))
option("UAutoDispose:Lenient", "true")
}
}
Android¶
plugins {
id "net.ltgt.errorprone" version "0.0.13"
}
dependencies {
errorprone "com.uber.autodispose:autodispose-error-prone-checker:x.y.z" // where x.y.z is the latest version.
errorprone "com.google.errorprone:error_prone_core:2.3.2" // Or whatever the latest version is
}
// Must go in afterEvaluate
afterEvaluate {
tasks.withType(JavaCompile).configureEach {
// Only if you want to support custom types with scopes
// Below is a sample configuration which includes Conductor
def classesWithScope = [
"com.bluelinelabs.conductor.Controller"
]
options.errorprone {
check("AutoDispose", CheckSeverity.ERROR)
option("AutoDispose:TypesWithScope", classesWithScope.join(","))
option("AutoDispose:Lenient", "true")
}
}
}
Maven¶
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.5</version>
<configuration>
<compilerId>javac-with-errorprone</compilerId>
<forceJavacCompilerUse>true</forceJavacCompilerUse>
<source>1.8</source>
<target>1.8</target>
<showWarnings>true</showWarnings>
<annotationProcessorPaths>
<path>
<groupId>com.uber.autodispose</groupId>
<artifactId>autodispose-error-prone</artifactId>
<version>x.y.z</version>
</path>
</annotationProcessorPaths>
<compilerArgs>
<!-- Only if you want to support custom configuration
Below is a sample configuration which includes Conductor -->
<arg>--XepOpt:AutoDispose:TypesWithScope=com.bluelinelabs.conductor.Controller</arg>
<arg>--XepOpt:AutoDispose:Lenient=true</arg>
</compilerArgs>
</configuration>
<dependencies>
<dependency>
<groupId>org.codehaus.plexus</groupId>
<artifactId>plexus-compiler-javac-errorprone</artifactId>
<version>2.8</version>
</dependency>
<!-- override plexus-compiler-javac-errorprone's dependency on
Error Prone with the latest version -->
<dependency>
<groupId>com.google.errorprone</groupId>
<artifactId>error_prone_core</artifactId>
<version>2.3.2</version>
</dependency>
</dependencies>
</plugin>
</build>
Report example¶
The following code snippet:
public class ComponentWithLifecycle extends Activity {
public void observeOnSomething() {
Observable
.interval(1, TimeUnit.SECONDS)
.subscribe(new Consumer<Long>() {
@Override public void accept(Long interval) throws Exception {
System.out.println(interval);
}
});
}
}
would produce the following error:
./gradlew build
error: [AutoDispose] Missing Disposable handling: Apply AutoDispose or cache the Disposable instance manually and enable lenient mode.
.subscribe(new Consumer<Long>() {
^
(see https://github.com/uber/AutoDispose/wiki/Error-Prone-Checker)
Would lead to this error at compile-time.
Configuration¶
Scopes¶
By default the checker is applied to AutoDispose interfaces and standard Android components with lifecycles: 1. Activity 2. Fragment 3. Support Fragment 4. LifecycleScopeProvider 5. ScopeProvider 6. LifecycleOwner
This can be configured by Error-Prone’s command line flags. The following flag is supported and takes input in a form of comma separated list of fully qualified class names of classes with scopes:
-XepOpt:AutoDispose:TypesWithScope=com.bluelinelabs.conductor.Controller,android.app.Activity
This flag adds the provided custom scopes to the default scopes mentioned above.
Overriding Scopes¶
If you only want the error prone check to run on your custom scopes and not the default ones, you can simply override the default scopes by adding the OverrideScopes
flag like so:
-XepOpt:AutoDispose:OverrideScopes=true
Lenient¶
Lenient
is a mode to ask the checker to be lenient when capturing returned Disposable
types. What this means is that if an rx subscribe
method is called and its returned Disposable
is captured, AutoDispose this code is manually managing the subscription and show ignore it. The same applies for capturing the returned value of subscribeWith
if the input type implements Disposable
.
This can be configured by Error-Prone’s command line flags. The following flag is supported and takes input in a form of a boolean true
or false
:
-XepOpt:AutoDispose:Lenient=true
The default value of this is false
.
Examples
// This is allowed in lenient mode
Disposable d = Observable.just(1).subscribe();
// This is allowed in lenient mode, because the subscribeWith arg type is Disposable
DisposableObserver<Integer> do = Observable.just(1).subscribeWith(new DisposableObserver...)
// This is not allowed in lenient mode, because the subscribeWith arg type is not Disposable
Observer<Integer> do = Observable.just(1).subscribeWith(new Observer...)
// This is not allowed in lenient mode, because the return value is not captured
Observable.just(1).subscribe();
// This is not allowed in lenient mode, because that subscribe() overload just returns void
Observable.just(1).subscribe(new Observer...)