Overview

Android, Maven and Hudson. Pardon me, Jenkins.

6 Comments

Android platform is based on Java but is somehow different. It compiles into Dalvik rather than into Java byte code and runs in emulator which is enough to make some of your standard Java tools fail and become unusable. There was one specific problem I was interested in. I must say, there is number of articles describing how to build Android applications using Maven and CI environment but none of those was helpful enough for me. I had to mash up things I’ve learned from all of those in order to make it work. So, the goal of this article is present a setup of simple Android-Maven project and to show how to configure it to run nicely on Hudson. Pardon me, Jenkins. Hopefully, this article will be enough for you to do the same.

First of all you will have to have Java installed (naturally), Eclipse (in my case it was Helios), Maven and Android SDK. Along with that, you will have to configure your Eclipse (Android SDK location, Java JDK, Maven) but I’ll skip that and act as it is all already configured properly.

What we need as additional tools? Some Eclipse plug-ins, of course. We need M2Eclipse plug-in to ease up work with Maven projects, Android Development Toolkit to ease up work with Android projects and bridge between those two to ease up work with Maven-Android projects: Maven Integration for Android Development Tools plug-in.

When those plug-ins are installed, we can create our first AVD (Android Virtual Device) – it will actually be an instance of emulator with specific options and features which we will use for testing the application. It can be created using Android SDK and AVD Manager by pressing the small Android button marked on the pic bellow. Once the AVD Manager is started, new window is opened and user can create virtual device (by pressing the button “New”) and specify its features: camera support, GPS support, existence of SD card, etc… Information regarding created virtual devices is placed in ${USER_HOME}/.android/avd. Each AVD will have its own directory and its own ini file. You will distinguish it easily by name you have given to the virtual device.

At the moment we have IDE set up, emulator is ready, but we don’t have any application to run. So, it is the right time to create new project. To state it once more, we want it to be Maven-Android project.

These are the steps to create new Android project in Eclipse:
File -> New -> Other -> Android -> Android project -> new dialog opens
– give project a name
– choose location for your new project
– choose API level (Android platform you want your application to runs on)
– give you application a name
– choose package name (where your sources will be)
– choose main activity name (optional)
– specify minimal API level your application will require
– click next -> new dialog opens

When prompted to create new test project, please skip that action, as we will come to that later after a bit of configuration of actual application project.

So, we have created new Android project and its structure is similar to this one,example project structure
but we want to make it Maven project also. For that reason we have to create pom file with all dependencies and enable Maven dependency management in Eclipse.

When it is enabled, Maven took over and slightly changed the structure of our project. For example, from now on we don’t need bin directory (which was default output for Android project) – directory named target is place where class files will go. This specific fragment from our pom file

<build>
<pluginManagement>
<plugins>
<plugin>
<inherited>true</inherited>
<groupId>com.jayway.maven.plugins.android.generation2</groupId>
<artifactId>maven-android-plugin</artifactId>
<version>2.8.3</version>
<configuration>
<deleteConflictingFiles>true</deleteConflictingFiles>
<undeployBeforeDeploy>true</undeployBeforeDeploy>
<sdk>
<platform>8</platform>
</sdk>
<device>emulator</device>
<emulator>
<avd>Device1</avd>
<wait>60000</wait>
</emulator>
</configuration>
<extensions>true</extensions>
<executions>
<execution>
<id>alignApk</id>
<phase>package</phase>
<goals>
<goal>zipalign</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</pluginManagement>
<plugins>
<plugin>
<groupId>com.jayway.maven.plugins.android.generation2</groupId>
<artifactId>maven-android-plugin</artifactId>
</plugin>
</plugins>
</build>

tells Android which emulator instance will start when we start the app. The name of the specified AVD must be the same as the name of the AVD we created with AVD manager. It means that, at this point, we have the simplest application that can be run on emulator by choosing Run As -> Android Application from its context menu.

With this all done and set, it’s time to create test project. What is test project? Test project is separate project containing only tests and resources needed for tests. “But, shouldn’t unit tests be contained by the same project where application is?”, one could ask. Yes, that’s absolutely right. These are not unit tests. These are acceptance tests. Unit tests should be in application project, in test directory.

So, here are the steps to create test project:
right-click on application project -> New -> Other -> Android Test Project -> new dialog opens
– give test project a name
– choose location for your test project
– choose project which you want to test
– choose application name
– other values are set automatically
– click finish

The result is new Android project, as it was when we created our application project, so create pom file and enable maven dependency management. This is the right moment to point out some important things regarding test project configuration. This is how pom build fragment should look like:

<build>
<plugins>
<plugin>
<groupId>com.jayway.maven.plugins.android.generation2</groupId>
<artifactId>maven-android-plugin</artifactId>
<extensions>true</extensions>
<configuration>
<enableIntegrationTest>true</enableIntegrationTest>
<autoStartEmulator>true</autoStartEmulator>
<deleteConflictingFiles>true</deleteConflictingFiles>
<undeployBeforeDeploy>true</undeployBeforeDeploy>
<sdk>
<platform>8</platform>
</sdk>
<device>emulator</device>
<emulator>
<avd>Device1</avd>
<wait>60000</wait>
</emulator>
</configuration>
</plugin>
</plugins>
</build>

This way we told maven to run integration tests and to start emulator (AVD with name Device1) when it’s time to do so. Furthermore, we told it to run emulator with API level 8 (Android 2.2) and to wait one minute before running tests to give time to emulator to fire up. It is very important to say which are dependencies that we need to test a project. Naturally, we need Android and Android test libraries. Also, Robotium can ease the job very much, so I added that one too. At the end, we need dependency to the project we are testing, both jar and apk. Jar dependency is needed to provide compiler with java classes and apk is needed to provide application to run tests against it on emulator. So, dependency pom fragment should look similar to what follows:

<dependencies>
<dependency>
<groupId>de.codecentric</groupId>
<artifactId>example</artifactId>
<version>${appproject.version}</version>
<type>apk</type>
</dependency>
<dependency>
<groupId>de.codecentric</groupId>
<artifactId>example</artifactId>
<version>${appproject.version}</version>
<type>jar</type>
</dependency>
<dependency>
<groupId>com.google.android</groupId>
<artifactId>android</artifactId>
<version>${android.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.google.android</groupId>
<artifactId>android-test</artifactId>
<version>${android.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.jayway.android.robotium</groupId>
<artifactId>robotium-solo</artifactId>
<version>${robotium.version}</version>
</dependency>
</dependencies>

When have all of this set up, it’s time to configure Hudson, i.e. Jenkins. What we need is Android Emulator Plugin (http://wiki.jenkins-ci.org/display/JENKINS/Android+Emulator+Plugin). This is plugin that will let you automatically generate and run an Android emulator for the duration of a build, with the emulator logs being captured as artifacts. Since this post is having tendency to become really big, I will not provide details about its configuration, but will tell you that you can find all that you need if you follow link I provided.

After you configured Android plugin to act as you want it to and wired up Hudson, pardon me, Jenkins, with you SCM tools, your CI-Android environment is ready. And this is exactly what we wanted to have. In addition, if you want to run more than one Android emulator instances in parralel, you might want to take a look at this plugin: http://wiki.jenkins-ci.org/display/JENKINS/Xvnc+Plugin.

I hope I helped a bit.

Kommentare

  • Manfred Moser

    Great post. If you want to learn more details about this and other Android, Maven and testing related topics you should come to my sessions at AnDevCon in March.

  • Daniela Grammlich

    4. March 2011 von Daniela Grammlich

    Hi,

    thanks for this great post!
    I have one problem left. When everything is set up, the console tells me:

    “/JenkinsTemplate/gen already exists but is not a source folder. Convert to a source folder or rename it.”

    I didn’t find a good solution for this problem. Making /gen a source folder throws other errors. Maybe you can help me? I use the latest releases.

    Kind regards
    Dani

  • Dusan Zamurovic

    5. March 2011 von Dusan Zamurovic

    Hi, Daniela

    I also had that problem several times and it always emerged at the start of the project. Although, I’ve never seen it with Jenkins involved, but only in my IDE (Eclipse). It was always caused by bad project configuration – I would say that IDE plugins we use are bit unstable and not completely ready to work on jump start. Sometimes project configuration goes OK and without any problems, sometimes it doesn’t and this issue occurs.
    In my case solution was right click on project -> maven -> Update Project Configuration. This is how my project file looks like, maybe it can help you too see if setup went well:

    [buildSpec]
    [buildCommand]
    [name]org.eclipse.wst.common.project.facet.core.builder[/name]
    [/buildCommand]
    [buildCommand]
    [name]com.android.ide.eclipse.adt.PreCompilerBuilder[/name]
    [/buildCommand]
    [buildCommand]
    [name]org.eclipse.jdt.core.javabuilder[/name]
    [/buildCommand]
    [buildCommand]
    [name]org.maven.ide.eclipse.maven2Builder[/name]
    [/buildCommand]
    [buildCommand]
    [name]com.android.ide.eclipse.adt.ResourceManagerBuilder[/name]
    [/buildCommand]
    [/buildSpec]
    [natures]
    [nature]com.android.ide.eclipse.adt.AndroidNature[/nature]
    [nature]org.maven.ide.eclipse.maven2Nature[/nature]
    [nature]org.eclipse.jdt.core.javanature[/nature]
    [nature]org.eclipse.wst.common.project.facet.core.nature[/nature]
    [/natures]

    (Sorry for tags, this fragment should be xml.)

    In some occasions, even with proper project file, Eclipse was showing this error. Then I just deleted it from the list of errors and warnings and it never appeared again. I know this is not “scientific” solution, but it worked for me.

    And one more thing to point out. Several times, after some time working on project, it happened that project configuration got somehow changed without me wanting it to be changed. Than you can expect different kinds of problems in IDE. Solution to that is to close project and/or IDE and manually fix project file to look like in my example.

    I hope I understood you problem well and that my answer will fix it.

  • Igor

    Hi!
    Great tutorial! Thanks for publish it.
    Could you please post the sample test project which i can load in Jenkins and get simple report?
    I’m sorry if i’m took your time.
    Thanks again and best regards to you!

  • Dusan Zamurovic

    18. June 2011 von Dusan Zamurovic

    Hi, Igor!

    I am glad you liked the article.

    Unfortunately, I am not able to provide you example project at the moment – I am on vacation and won’t be back in office for few weeks.
    I hope this blog post itself will be sufficient for you.

    • Android user

      15. November 2011 von Android user

      Hi!

      Very useful blog. But, can you please post the sample test project which i can load in Jenkins and get simple report?

      many thanks and best regards

Comment

Your email address will not be published. Required fields are marked *