KlassIndex is the younger Kotlin brother of atteo/classindex. However, it differs from ClassIndex in various aspects.
Aspects | ClassIndex | KlassIndex |
---|---|---|
Language | Java | Kotlin |
Supported Classes | Any Java class | Any Kotlin class |
Supported Build Tools | Maven and Gradle | Gradle |
Supported Scopes | Annotations, Subclasses, Packages | Annotations, Subclasses5 |
Service Loader Support | Yes | No, superfluous6 |
JaxB Index | Yes | No |
Stores Documentation | Yes | No |
Android Support | Limited2 | Yes |
Runtime Performance | Great | Even Greater1 |
Filtering Support | Limited | Complete functional support3 |
Extension Support | Yes | Theoretically |
Index external classes | Yes, by extending the processor | Yes, using kapt arguments |
Jar Shading Support | Yes | Maybe |
Compile Time Safety | Limited4 | Complete |
Class Loader Required | Yes | No |
License | Apache 2.0 | Apache 2.0 |
Iterable
, not just filters.getAnnotated()
getSubclasses()
KlassIndex
plugins {
// Replace with the latest Kotlin version
id "org.jetbrains.kotlin.kapt" version "1.+"
}
// Replace with the latest versions from Jitpack
compile 'fyi.fax.klassindex:library:4.+'
kapt 'fyi.fax.klassindex:processor:4.+'
kapt {
useBuildCache = true
}
plugins {
// Replace with the latest Kotlin version
kotlin("kapt") version "1.+"
}
// Replace with the latest versions from Jitpack
compile("fyi.fax.klassindex:library:4.+")
kapt("fyi.fax.klassindex:processor:4.+")
kapt {
useBuildCache = true
}
@IndexAnnotated
annotation class YourAnnotation
KlassIndex.getAnnotated(Component::class)
@IndexSubclasses
interface YourSuperclass
KlassIndex.getSubclasses(YourSuperclass::class)
Filtering allows you to select only classes with desired characteristics. Here are some basic samples:
KlassIndex.getAnnotated(SomeAnnotation.class).topLevel()
KlassIndex.getAnnotated(SomeAnnotation.class).topLevel().withModifiers(Modifier.PUBLIC)
KlassIndex.getAnnotated(SomeAnnotation.class).annotatedWith(SecondAnnotation::class).objects()
For more examples, check the test file.
Sometimes, you cannot easily use annotations to trigger compile time indexing
because you don't control the source code of the classes which should be annotated.
For instance, you cannot add @IndexSubclasses
meta-annotation to @Exception.
To add the regarding annotations to the desired external class, just add an argument to kapt.
kapt {
arguments {
arg(
"fyi.fax.klassindex.IndexSubclasses", // IndexAnnotated alternatively
"java.lang.Exception" // this is a vararg
)
}
}
Please consider that this option only provides you internal classes at the moment.
That means, for the Exception
example, you will only get your declared exceptions, not all available Java and Kotlin exceptions.
Make sure not to use Kotlin type aliases, they will not be recognized (e.g., not kotlin.Exception
).
KlassIndex indexes your classes at compile time by providing the implementation of the standard annotation processor. The index is then used by kapt utilizing kotlinpoet to generate new Kotlin source files that hold the static references to the indexed classes. The compiler uses the source files as if they were manually written.
KlassIndex provides a library to access the statically compiled index from the generated classes and to process them.
Traditional classpath scanning is a very slow process. Replacing it with compile-time indexing speeds Java applications bootstrap considerably.
Here are the results of the benchmark comparing ClassIndex with various scanning solutions.
Library | Application startup time |
---|---|
None - hardcoded list | 0:00.18 |
Scannotation | 0:05.11 |
Reflections | 0:05.37 |
Reflections Maven plugin | 0:00.52 |
Corn | 0:24.60 |
ClassIndex | 0:00.18 |
KlassIndex | TBD |
Notes: benchmark was performed on Intel i5-2520M CPU @ 2.50GHz, classpath size was set to 121MB.