Using AAR dependencies in API library projects

Android uses the AAR format for distributing libraries. By default Maven cannot handle this format as a dependency type. Fortunately the android-maven-plugin adds some support. If you use this library you can declare dependencies like this:

        <dependency>
            <groupId>com.obt</groupId>
            <artifactId>sdk</artifactId>
            <version>1.0.3</version>
            <type>aar</type>
        </dependency>

This works fine with some restrictions as long as your projects packaging is either AAR or APK. It doesn’t work, when developing a cross platform API. These APIs are usually packaged as a single JAR, that contains the implementations for all platforms, so there’s no AAR support at all. The solution to this is to add an extra Maven module to your project, which unpacks an AAR dependency and deploys the classes.jar to your local repository. Here’s an example, where we take an AAR dependecy (org.apache.cordova:framework:8.1.0) and redeploy it:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>com.dukescript.api</groupId>
        <artifactId>bluetooth</artifactId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <artifactId>deploy-cordova-platform</artifactId>
    <packaging>aar</packaging>
    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>
    <build>
        <plugins>
            <plugin>
                <groupId>com.simpligility.maven.plugins</groupId>
                <artifactId>android-maven-plugin</artifactId>
                <version>4.6.0</version> 
                <extensions>true</extensions>
                <executions>
                    <execution>
                        <id>unpack-dependecy</id>
                        <phase>package</phase>
                        <goals>
                            <goal>unpack</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
            <plugin>
                <!-- install  the jar -->
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-install-plugin</artifactId>
                <version>2.5.2</version>
                <executions>
                    <execution>
                        <id>cordova</id>
                        <phase>package</phase>
                        <goals>
                            <goal>install-file</goal>
                        </goals>
                        <configuration>                  
                            <file>target/unpacked-libs/oac_framework_8.1.0/classes.jar</file>
                            <groupId>org.apache.cordova</groupId>
                            <artifactId>framework</artifactId>
                            <version>8.1.0</version>
                            <packaging>jar</packaging>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>
    <dependencies>        
        <dependency>
            <groupId>org.apache.cordova</groupId>
            <artifactId>framework</artifactId>
            <version>8.1.0</version>
            <type>aar</type>
        </dependency>
    </dependencies>
</project>

The android-maven-plugin provides support for unpacking the AAR, while the “maven-install-plugin” is used to deploy it to th local repo. In our API library, we set a dependency on this project to establish the build order. After that we can use the dependecy from the local repository with no extra hacks.

Admittedly this is not perfect, because we’re ignoring the extra resources that might be packaged in the AAR. But for most dependencies it works just fine as a quick solution. An extra bonus is, that dependencies redeployed as JARS are recognized by IDEs like NetBeans, so you get full code completion and no extra error marks due to “missing” dependencies.

Enjoy writing APIs with DukeScript!