0

I use Maven and I need to process classes from another dependencies. Before processing the classes, maven-dependency-plugin is used to unpack those dependencies with the unpack-dependencies goal, so then I can process the classes in the target directory. Everything is fine while the referenced dependencies are packaged as JARs. Now I'm faced with an AAR dependency that is required to be class-processed in a special way. The error I get so far is:

Failed to execute goal org.apache.maven.plugins:maven-dependency-plugin:2.10:unpack-dependencies (aars-only) on project app-android: Unknown archiver type: No such archiver: 'aar'. -> [Help 1]

The aars-only execution identifier comes from the configuration below, but in general it gives the same error if not splitting the executions. Here is my maven-dependency-plugin configuration I have split later into two executions:

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-dependency-plugin</artifactId>
    <executions>
        <execution>
            <id>jars-only</id>
            <phase>process-classes</phase>
            <goals>
                <goal>unpack-dependencies</goal>
            </goals>
            <configuration>
                <includeScope>runtime</includeScope>
                <includeGroupIds>foo-group,bar-group</includeGroupIds>
                <includeTypes>jar</includeTypes> <!-- this is necessary to skip AAR dependencies -->
                <outputDirectory>${project.build.directory}/classes</outputDirectory>
            </configuration>
        </execution>
        <execution>
            <id>aars-only</id>
            <phase>process-classes</phase>
            <goals>
                <goal>unpack-dependencies</goal>
            </goals>
            <configuration>
                <includeScope>runtime</includeScope>
                <includeGroupIds>baz-group</includeGroupIds>
                <includeTypes>aar</includeTypes> <!-- hoping this can process AARs as well, but it's just another execution, nothing special -->
                <outputDirectory>${project.build.directory}/classes</outputDirectory>
            </configuration>
        </execution>
    </executions>
</plugin>

Commenting out the aars-only execution leads to a runtime application crash, but the build passes as the jars-only execution includes the jar type only -- not exactly what I need.

How do I unpack the AAR dependency (baz-group) to the target/classes directory? Is it possible to configure the maven-dependency-plugin somehow so it could accept AAR and its packed classes.jar? Or is there any other way to make it work probably just using another plugin?

(Maybe it's a useful hint: I also use com.simpligility.maven.plugins:android-maven-plugin.)

Lyubomyr Shaydariv
  • 20,327
  • 12
  • 64
  • 105
  • I don't have a Maven installation on this machine to test on, but I would speculate that as there are a number of threads on forums pointing out this issue, the MDP simply won't unpack an AAR. If you can unpack it using an ANT task, embedding an ANT phase into your POM is probably the best option. AAR should work with the ANT unzip task. – Alex Nov 26 '15 at 14:01

1 Answers1

1

It looks as though the MDP plugin won't work with this directly.

As pointed out in this thread - How to convert AAR to JAR, the AAR is essentially a zip with other archive information in it.

There are 2 possible approaches I can see here.

1) - Use ANT to unzip the AAR, find the jar file contained in it, then unzip with ANT as well.

2) - Use ANT to unzip the AAR as before, then copy it to an intermediate folder, and use the maven-dependency-plugin to unpack the jar.

https://maven.apache.org/guides/mini/guide-using-ant.html

I'm not able to test this, but this POM snippet might be of use as a starting point.

<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-antrun-plugin</artifactId>
<version>1.6</version>
<executions>
    <execution>
        <id>prepare</id>
        <phase>build</phase>
        <configuration>
            <tasks>
                <unzip src="source/my_archive.aar" dest="output/" />
                <copy file="output/classes.jar" tofile="my_archive.jar"/>

                <!-- 
                     Either extract the jar here, 
                     or place it where the maven dependencies plugin 
                     can find it, and extract it in a later build phase 
                -->
            </tasks>
        </configuration>
        <goals>
            <goal>run</goal>
        </goals>
    </execution>
</executions>

Community
  • 1
  • 1
Alex
  • 1,643
  • 1
  • 14
  • 32
  • Thank you for the answer. Frankly speaking, I try to avoid Apache Ant as much as possible, and haven't even introduced `maven-antrun-plugin` in my build process based on 100+ modules that use Maven only. Can't believe I can't use Maven here only. Regarding your idea: how do I specify the source AAR assuming the AAR is in the local repository? – Lyubomyr Shaydariv Nov 26 '15 at 14:17
  • I'm also wondering if there's a Maven plugin to process ZIP containers. And even more wondering why `maven-dependency-plugin` still does not allow to deal with AARs as if they are regular dependencies. My first thought was: "No, can't believe it, it must be able to do it", but yes, I also googled for a few hours and found just a few old threads complaining the lack of the support. Another thought was if there could be an extension for `maven-dependency-plugin` similar to a mechanism `android-maven-plugin` uses to expose the `aar` packaging in the `pom.xml` root. I feel disappointed... – Lyubomyr Shaydariv Nov 26 '15 at 14:17
  • I'm with you on Ant, it's a pain to use! However, there are a number of occasions where Maven just couldn't handle the configuration we were trying to use. I've used Ant with maven to unpack C++ binaries from an archive prior to a build before, which used ant to move the zip and extract it. If you add the AAR as a normal dependency in Maven, then using and Ant task, unzip the files with the .aar extension. This should give you the jars in the build directory. It's been a while since I've done this, so I appologise for it not being very clear. – Alex Nov 26 '15 at 14:25
  • The maven dependency plugin should be sufficient to extract a zip, but as it doesn't like the AAR archive type (regardless of it really just being a zip), Ant may be the better option. I do agree, Maven should just handle this, but if your build is event slightly unorthodox, ant gives more fine-grained control. This may be possible with the maven-dependency-plugin, but you would have to extract the aar to get the jars, then extract the jars in another phase. – Alex Nov 26 '15 at 14:31
  • Thank you for your comments, Alex. And probably the last question, please: how do I specify the exact `src` attribute for the `unzip` task assuming that the ready-to-unzip source is in the repository (simply speaking, just get the absolute path of the AAR in the local repository)? I seem to be blind to figure out how to do this. – Lyubomyr Shaydariv Nov 26 '15 at 14:40
  • You wouldn't need to get the path to the AAR in the repo, simply add the AAR as a dependency. When maven build the project, the artifact will be downloaded from your local repo to the maven build directory. Once it's there, you can reference it via the ant task, so you will be pointing to an aar file in the build directory of your project. The copy tast int he POM snippet can be used to move the AAR or the extracted Jars to wherever they are needed by maven. – Alex Nov 26 '15 at 14:45
  • I'm sorry, but I've not got a Java development system set up at the moment since moving to C#, so I've got no way to test this. This approach should work, but you may need some trial and error. I've used this method before when building a project that relied on a number of C++ libs. They were downloaded from the repo, packaged in a zip, and extracted to the build directory by an ant task, and another ant task packaged them into a jar for distribution. We tried to do the same thing in pure maven, but lost a week trying to make it work. – Alex Nov 26 '15 at 14:48
  • I've just managed it to work. Fortunately, `${project.build.directory}/unpacked-libs` is created by `android-maven-plugin` and the directory is accessible in the `process-classes` phase (also, it's not very convenient to configure the `src` attribute though (it's named dynamically). This is somewhat that diverges from what you say about the copied artifacts (and this is what `maven-dependency-plugin` is for), but this is fully enough for me, and it works brilliantly! You're the life-saver, Alex. Thank you! :) – Lyubomyr Shaydariv Nov 26 '15 at 15:42
  • Here is my `maven-antrun-plugin` snippet: `` – Lyubomyr Shaydariv Nov 26 '15 at 15:43
  • Ahh, so the android plugin already extracted it! I hadn't realised it did that. I'm glad I could point you in the right direction, I'm just sorry I couldn't be more specific in my answer, but regardless, you're very welcome. – Alex Nov 26 '15 at 15:47