Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why isn't my pom being executed correctly when using Android Studio/IntelliJ?

I have an Android application which is built with Maven. Using the buildnumber-maven-plugin and maven-resources-plugin I insert the maven project version and the git commit hash into the AndroidManifest. The create goal of buildnumber-maven-plugin runs in the validate phase and the resources goal of the maven-resources-plugin runs in the initialize phase.

When built through the command-line (with mvn install) all works fine and the build number appears correctly in the produced manifest.

However when building through Android Studio or IntelliJ the git commit hash is not present (the Maven property is not replaced with the actual value) in the manifest but the maven project version is.

Why?



FYI: Android Studio runs the Maven phase process-resources before a Make, so it should work.

On the command-line I am using Maven 3.0.3, so it could be a version issue (though I can't find out what version IntelliJ uses).

Here is my POM's build element:

<build>
    <sourceDirectory>src</sourceDirectory>
    <testSourceDirectory>test</testSourceDirectory>

    <resources>
        <resource>
            <directory>${project.basedir}</directory>
            <filtering>true</filtering>
            <targetPath>${project.build.directory}/filtered-manifest</targetPath>
            <includes>
                <include>AndroidManifest.xml</include>
            </includes>
        </resource>
    </resources>

    <plugins>
        <plugin>
            <groupId>org.codehaus.mojo</groupId>
            <artifactId>buildnumber-maven-plugin</artifactId>
            <version>${maven.buildnumber.version}</version>
            <configuration>
                <doCheck>false</doCheck>
                <doUpdate>false</doUpdate>
                <shortRevisionLength>6</shortRevisionLength>
                <revisionOnScmFailure>000000</revisionOnScmFailure>
            </configuration>
            <executions>
                <execution>
                    <phase>validate</phase>
                    <goals>
                        <goal>create</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>

        <plugin>
            <artifactId>maven-resources-plugin</artifactId>
            <version>${maven.resources.version}</version>
            <executions>
                <execution>
                    <phase>initialize</phase>
                    <goals>
                        <goal>resources</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>

        <plugin>
            <groupId>com.jayway.maven.plugins.android.generation2</groupId>
            <artifactId>android-maven-plugin</artifactId>
            <extensions>true</extensions>
            <configuration>
                <androidManifestFile>${project.build.directory}/filtered-manifest/AndroidManifest.xml</androidManifestFile>
            </configuration>
        </plugin>
    </plugins>
</build>

And the versionName in my AndroidManifest file is:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.somecompany"
    android:versionCode="1"
    android:versionName="${project.version}-${buildNumber}" >

From commandline both ${project.version} and ${buildNumber} are filled in correctly with their values, from IntelliJ ${buildNumber} is not and just appears as "${buildNumber}": this would indicate (since I have set revisionOnScmFailure) that the plugin fails to run at all.

I have tried changing the create goal to run in the initialize phase (in case IntelliJ was skipping out validate) but that made no difference.

like image 303
Joseph Earl Avatar asked Jun 25 '13 15:06

Joseph Earl


1 Answers

IntelliJ has it's own internal build system much like any other IDE and is able to build projects without the help of external tools. Intellij also integrates with Maven by interpreting the pom.xml from your project and intructing it to build based on the configuration you have defined. This works pretty well with most compilation tasks but starts to fall over when you bring in more complex plugins such as the buildnumber-maven-plugin. Unfortunately IntelliJ has no internal equivilent to handle this plugin so the ${buildNumber} property is never populated.

The possible workarounds are:

  1. Don't build your project with IntelliJ's built in system, use the "Maven Projects" panel which you can show by going to "View" > "Tool Windows" > "Maven Projects". This gives you access to all of the standard Maven phases and other features.

  2. In your IntelliJ "run configuration" add an environment variable called "buildNumber" and give it any value you like, for example: buildNumber=DEV. This will make the the buildNumber property available during the build process and populate the property, it won't however update from your SCM.

We use the first workaround on a multi-module maven project as we too have hit similar limitations with the buildnumber-maven-plugin. We also use solution 2 when we need to run an integration test in IntelliJ as the buildNumber property is required by our code to display version information, as long as we give it any value it's happy.

I hope this is somewhat useful to you, the only real solution would be for IntelliJ's internal build system to have some understanding of the buildnumber-maven-plugin and expose the correct properties to the environment during the build process.

like image 193
Robert Hunt Avatar answered Sep 19 '22 12:09

Robert Hunt