Packaging
Use the embed
configuration to include dependencies in a module's packaged output.
Declaring an embed
dependency only includes it in the packaged output, it does not make that dependency available
during compilation! If you wish to reference any classes in the embedded dependency in your Gradle module, you will also
need to declare it as a compileOnly
dependency as shown above.
Note
compileOnly
and embed
dependencies will not show up in the published pom file unless also declared as api
or
implementation
dependencies.
In Android modules, embed configurations can also be declared for individual build types, including custom ones:
META-INF files¶
You can also let the plugin know whether to strip all META-INF/
files from the packaged output file. By default it
keeps them all, but this can be configured via the plugin extension:
Packaging Options for Android Libraries¶
The packaging
block in
an Android module's build script is used to handle the packaging of resources and JNI libraries. This plugin also uses
those same rules to configure handling of resources and JNI libraries merge conflicts when merging multiple aar files
together.
Post-Processing¶
The plugin allows you to register custom processors that will be executed after the merged archive has been created. This can be useful for logging, validation, or applying other operations that you may want to perform on the merged archive. To register a processor, you must first create a factory that will be used to create instances of your custom processor via the plugin extension:
Note that your factory must be Serializable
.
The factory can also be registered by passing in only the class name, which will be used to reflective instantiate an instance at task execution. This is useful if your factory is not available on the Gradle buildscript classpath. In doing so, you must ensure that your factory has a public no-arg constructor so that it can be properly created:
Processors are executed in the order they are registered. The factory interface is very straightforward and only defines
a create()
method for you to implement. This method should return an instance of your custom
ArtifactArchiveProcessor
implementation that will be executed on the merged archive.
API Jar for Android Libraries¶
The api.jar
file is an optional element inside an aar archive that helps developers using the library understand its
exposed classes, methods, and functionalities. When this file exists in an aar, it will be used it as the source of
truth for which members can be referenced at compilation time.
Generating a custom api.jar
file can be used to hide certain public members from IDE autocomplete, though they
can still be referenced and invoked via reflection at runtime as per usual.
Generating this file begins with registering an ArtifactArchiveProcessor.Factory
factory to create a subclass of
ApiJarProcessor
. The processor implementation is where the api.jar
transformation occurs. When enabled, it is
provided with a representation of the current set of classes defined in the merged aar archive, as well as a reference
to the merged archive itself. While the archive is immutable, the classpath provided is mutable and supports a variety
of transformations, including but not limited to:
- Removing existing classes and class members (constructors, methods, and fields).
- Defining entirely new classes with custom members.
- Renaming classes and class members or modifying their access visibility.
- Adding or removing annotations on classes and class members.
An example implementation can be seen below, which is used to remove a public class and a public method that are both meant for internal use only:
class MyApiJarProcessor : ApiJarProcessor {
override fun processClasspath(aarArchive: AarArchive, classpath: MutableClasspath) {
// Remove internal class
classpath.removeClass("com.example.TerminalSdkInternal")
// Remove internal method on public class
val fooClass = classpath.get("com.example.TerminalSdk")
fooClass.methods = fooClass.methods.filter { !it.name.contains("internal", ignoreCase = true) }
}
}
class MyApiJarProcessor implements ApiJarProcessor {
@Override
void processClasspath(@NotNull AarArchive aarArchive, @NotNull MutableClasspath classpath) {
// Remove internal class
classpath.removeClass("com.example.TerminalSdkInternal")
// Remove internal method on public class
def fooClass = classpath.get("com.example.TerminalSdk")
fooClass.methods = fooClass.methods.findAll { !it.name.containsIgnoreCase("internal") }
}
}
Further documentation for the kind of transformations available can be found by referencing
API documentation for the
sh.christian.aaraar.model.classeditor
package.
Modifying Enums
At this time, creating new enum classes or modifications to existing enum classes will be ignored.
Modifying Parameter Names
By default, parameter name metadata is not included in class files. If you wish to include parameter names in the
compiled classes.jar
and api.jar
files, you must compile your library with additional flags in order to embed
this data in your compiled class files: