My Gradle Tips and Tricks 1

gradle_logoThe new Android build system is based in Gradle, an advanced build tool that simplifies build automation.

I used Maven for many years and Gradle project structure is very similar, but Gradle configuration files are Groovy-based and much (much!) more simple. Here is the official documentation

This week I migrated a lot of my Android and GWT projects to Gradle (some of them in my github), and here are some tips that I discovered (and I will add more as I find them):

Embrace the new Source Structure

Initially can be difficult, but putting the code under /src/main/java/, Android resources in /src/main/res/, etc. is a very popular form to organize the code. You can configure the build.gradle file to keep the old Android project structure, but I suggest migrating to the new structure.

Reference Another Project in your Workspace

You have two options:

  1. Use a Multi-Project Build
  2. Install the artifact (JAR if is a standard Java library, AAR if an Android Library) in your local Maven repo

Both options are explained below:

Use Multi-Project Builds

You can create a multi-project setup with projects on subfolders adding a settings.gradle file at the root with a include statement:

include 'library-project', 'your-project'

Then inside a your-project’s build.gradle you can easily add a dependency to another project (called “other_project”):

dependencies {
    compile project(':library-project')
}

Sample here.

Install a JAR to your Local Maven Repo (with the source code)

With standard java libraries and a build.gradle file like:

apply plugin: 'java'
apply plugin: 'maven'
group = 'com.company'
version = '0.8'

You can do “gradle install” to copy it yo your Maven repo.

Manually Install a JAR to your Local Maven Repo (without source code)

At the moment a lot of Google artifacts (=JARs, AARs) are not available at the Maven Central repo, but you can install them manually to your local Maven repo

mvn install:install-file -Dfile=android-support-v4.jar -DgroupId=com.google -DartifactId=android-support-v4 -Dversion=0.1 -Dpackaging=jar

You can also do it with gradle, but it is a bit more complex sample here.

Reference an Artifact from your Local Maven Repository

Be careful to add mavenLocal() to your repositories in the build.gradle:

repositories {
    mavenLocal()
}

Then use a normal reference, for the android-support-v4.jar sample above, it will be:

dependencies {
    compile 'com.google:android-support-v4:0.1'
}

Install an AAR to the Local Maven Repository

AAR is the new package format for Android Libraries. The “gradle install” task (that should install the AAR in the local Maven repository) does not works as expected in those projects, so I use a little hack:

apply plugin: 'maven'
uploadArchives {
  repositories {
    mavenDeployer {
      repository url: 'file://' + new File(System.getProperty('user.home'), '.m2/repository').absolutePath
    }
  }
}
task install(dependsOn: uploadArchives)

Usage sample here.

Android Library Projects need an Application Tag

This is an ADT bug, and the workaround is to add an empty application tag yo your library’s AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" ...>
    <application />

Include all the JARs in the libs/ Directory

This was the default behaviour of Android Projects, to maintain it you can add to your build.gradle:

dependencies {
    compile fileTree(dir: 'libs', include: '*.jar')
}

I suggest referencing local JARs only in final Android projects, referencing them in libraries can cause problems, read below:

Avoid Referencing Local JARs in Android and Java Libraries

If you reference local JARs in Android libraries, those jars are going to be embedded in the AAR. If you reference again the JAR from a project that uses the AAR you will see this build error:

:project:dexDebug
UNEXPECTED TOP-LEVEL EXCEPTION:
java.lang.IllegalArgumentException: already added: Landroid/support/v4/app/ActivityCompatHoneycomb;
//..
1 error; aborting
:project:dexDebug FAILED

If an Android Library projects references a JAR library, and the JAR library references local JAR files, those local JAR files are not going to be embedded in the Android projects using the library.

The best solution is to install all the JARs to your local Maven repo as explained above.

Or Embed all the Dependency JARs Into your Library

In some situations you may embed all the JARs in your library, but ONLY if those dependency JARs are not going to be referenced again in a project that uses the library.

jar {
    from configurations.compile.collect { it.isDirectory() ? it : zipTree(it) }
}

Android Projects Need Libraries Compiled with Java 1.6

If in an Android Project you use a library JAR including classes compiled with source compatibility to Java 1.7, build gives this WARNING:

trouble processing:
bad class file magic (cafebabe) or version (0033.0000)
...while parsing Class

…and the class is not included in the APK, so the app force closes at running.

This may be solved adding in the build.gradle of the library:

apply plugin: 'java'
sourceCompatibility = 1.6
targetCompatibility = 1.6

Create a Source JAR for a Library

Source JARs are needed for libraries used in GWT projects. To generate them add this to your build.gradle:

apply plugin: 'maven'
//...
task sourcesJar(type: Jar, dependsOn:classes) {
    classifier = 'sources'
    from sourceSets.main.allSource
}
artifacts {
    archives sourcesJar
}

You can install them to your local repo with “gradle install”

Include a Source JAR from Another Project

For multi-project_builds:

dependencies {
    compile project(':other_project')
    compile project(path: ':other_project', configuration: 'archives')
}

Sample here.

Include a Source JAR from a Maven Repo

Simply append “:sources”:

dependencies {
    compile 'com.company:artifact-name:0.8'
    compile 'com.company:artifact-name:0.8:sources'
}

Coding in the Dark Side (with Eclipse!)

screenshotGetting back to the old days where I used Emacs to code (ok, more than ten years ago), now I’m using a dark theme in Eclipse. Dark themes are less eye-stressing and now are becoming popular with editors like IntelliJ, Sublime Text and the last Visual Studio. But Eclipse is not so easy to setup in dark colors…

The Eclipse Juno platform supports styling of the SWT widgets via CSS, but many other elements must be setup manually, so I published my CSS and setup instructions in a GitHub repository: https://github.com/albertoruibal/eclipse_dark_css

Welcome to the dark side!


Chromium Embedded Framework

chromiumHTML5 is a fantastic app framework, but there are many environments where you cannot rely on the features support of the browser (specially when dealing against Internet Explorer, old windows versions or environments where you cannot freely upgrade the browsers). Recently I found this problem trying to package Mobialia Chess 3D for Windows 8. Microsoft provides some tools to package HTML apps to native apps, but they will run with the Internet Explorer engine, lacking features like WebGL, WebRTC, etc.

Chromium Embedded Framework (CEF) is a library that allows to embed a Chromium webview in your native Windows or Mac desktop application. So you can convert any HTML5 to a traditional desktop app (and I bet some users to try guessing if Mobialia Chess 3D is an HTML5 app). You can also create a Windows/Mac installer to  distribute the app (I used InnoSetup, but this is another story…).

Using CEF requires a small knowledge about Windows/Mac desktop app development. I created a Windows app using Visual Studio Express, it was not very difficult, because CEF includes a “cefclient” sample project that you can use as a template to start your project development.

The main problem that I found was the size, embedding CEF will add 45Mb size to your installed application. I also found other minor problems like the lack of mp3 sound support (due to license problems) solved converting the sound files to ogg.

CEF is already used by great desktop applications like Steam, Evernote or Spotify, so it’s a great option to consider in your developments.


Setting up the GoogleTV Emulator 2

Many people has problems with the Google TV Emulator because it hangs up booting at the Google TV logo. The problem is that it only works with specific device configurations and resolutions.

First you need to install the “GoogleTV Emulation Addon” using the Android SDK Manager. Then, create a new “Device Definition” (notice the new “Device Definition” tab at the top of the Android Virtual Device Manager in the lasts Android SDKs).

When prompted for the device definition parameters you must enter:

googletv1

This setup is for a 720p resolution, for a 1080p you must change the resolution to 1920×1080 and the density from tvdpi to xhdpi. Once the device definition is created, the next step is to create a new Android Virtual Device using it:

googletv2

Et voilà, our Google Tv emulator is up and running:

googletv3


3D Chess Google+ Hangout Plugin

gplus-hangout-60x230-normalThose days I’m working in Mobialia Chess&Chess at ICC with a lot of bug fixes and some new features… and as a side project I developed a “Mobialia Chess 3D” Google+ Hangout Plugin to play 3D Chess inside a Hangout.

You can start a chess hangout pressing the “Hangout” button in http://chess.mobialia.com or directly with the image button in this post. All the participants in the hangout can move the pieces, so it can be used to play video-call chess games or to teach chess lessons.

Technically it wasn’t very hard, the Google+ Hangouts API offers a shared state and notifications when the state changes, you can get all the API information at https://developers.google.com/+/hangouts/

I was thinking to use this API since I saw some hangout API demos by +Paul Kinlan at the BCN DevFest 2011, and recently  I had the final idea watching a Quobis WebRTC webinar.

I had only problems accessing frames from different domains, (prohibited to avoid Cross-Site-Scripting, XSS, attacks) because the hangout is hosted in a Google domain and the chess app in a different one.

To bypass those problems I used the HTML5 window.postMessage() API to send and receive messages between frames. You can send messages to frames in other domains passing two parameters to postMessage(): the message and the domain of the receiving frame:

<script type="text/javascript">
var message = "";
document.getElementById('iframeid').contentWindow.postMessage(message, "http://www.domain.com");
</script>
<iframe id="iframeid" height="100%" width="100%" src="http://www.domain.com/iframe.html"></iframe>

and in the receiving frame you must set a message listener:

window.addEventListener("message", function messageReceived(evt) {
    console.log("Receiving message from " + evt.origin + " : " + evt.data);
    //...
}

Note that you receive the origin domain, crucial because the domain of the hangout is different each time.


JavaScript as a Runtime

The future is here, and JavaScript (JS) is everywhere, but JS development is so hard that many people prefer to develop in other languages and then compile their code to JS, using JS as a universal runtime. Here are the most interesting options:

GWT

GWT stand for Google Web Toolkit, but now it’s in hands of the community and extensively used in many corporations. GWT compiles Java into JS and it’s strongly optimized. I use it a lot, and I feel very productive using an advanced IDE like Eclipse with tools like code assist, refactor, etc.

https://developers.google.com/web-toolkit/

CoffeeScript

A very compact language, inspired by Ruby and Python and that has become extremely popular in the last years. I’m not very familiar with the “Syntactic sugar” and I’m more productive with traditional languages (yes, I love curly backets! {}).

http://coffeescript.org/

Haxe

If you are an ActionScript developer (Adobe Flash), this is your language. It not only compiles to JS and ActionScript, also to PHP, C++, C#, etc. It’s becoming popular for the development of multi-platform mobile games with NME.

http://www.haxe.org/

Dart

This is a new language for the web pushed by Google. It tries to be a “modern and structured” language for the web that can be run directly into the browser, but to retain compatibility (and to run in other browsers that publicly rejected Dart), it can also be compiled to JS.

http://www.dartlang.org/

List of languages that compile to Js: http://altjs.org/


My Favourite HTML5 APIs

Ok, I’m supossed to be an Android developer, but i’m going back to HTML+JS for some projects, and I found that HTML5 has really powerful new APIS, these are my favourite:

  1. WebGL: Is changing the game rules, finally advanced 3D graphics in the browser. As it’s very hard to use directly,  I suggest the Three.js library
  2. Storage: A very simple system so store data in the browser, much more powerful than cookies
  3. Web Workers: Multithreading in Javascript, yes, now it’s possible
  4. WebAudio: a good sound API for the web, continues having some differences between browsers, but promises to be great

And I am already using this APIs in some Mobialia web apps:

App WebGL Storage Web Workers WebAudio
Mobialia Chess 3D X X X
Slot Racing X X X
Four in a Row X X

This apps are developed in Java with Google Web Toolkit (GWT), you can also view  my slides: Migrating apps from Android to HTML5 via GWT.


Google Chrome Frame

Recently I’m hearing that Internet Explorer 10 (IE) is great, etc. but IE continues lacking some standards like WebGL. I’m working with WebGL in some HTML5 projects like:

and I couldn’t make the IEWebGL plugin work (it requires a different initialization). But Google has a great solution: the Chrome Frame, it’s an Internet Explorer plugin that runs an embedded Chrome, making possible for some advanced web apps to run into IE. Not great enough? It works with IE 6,7, 8 and 9!

Using it in a web page is extremely easy: Adding this header to your web page, IE will use Google Chrome Frame if installed:

<meta http-equiv="X-UA-Compatible" content="chrome=1">

And you can also add this javascript code asking the user to install Chrome Frame if it isn’t available:

<!--[if IE]>
  <script type="text/javascript"
      src="http://ajax.googleapis.com/ajax/libs/chrome-frame/1/CFInstall.min.js">
  </script>

  <div id="prompt">
  </div>

  <script>
    window.attachEvent("onload", function() {
    CFInstall.check({
      mode: "overlay",
      node: "prompt"
    });
  });
  </script>
<![endif]-->

More Google Chrome Frame resources:


DevFest-X BCN 2012

For those who don’t follow me in the social networks, I’m now a co-organizator of the GDG Vigo (Google Developers Group), founded by Reinaldo Aguilera. In this group we are organizating a lot of interesting (and free!) Android and HTML5 activities (speechs, codelabs…) near Vigo, Galicia. Join to our Google Group and stay tuned!

This year I also went to the Barcelona DevFest, but as GDG Vigo we tried to help with the organization.

We participated in a Three.js codelab with Ricardo Cabello (Mr.Doob) showing how to make a very simple WebGL game in some simple steps. Slides are available at:

http://www.alonsoruibal.com/slides/codelab_three.js/

and source code is hosted in github: https://github.com/albertoruibal/codelab_three.js/

In another session I also told my experience migrating some Mobialia apps from Android to HTML5 with GWT, those slides are at http://www.alonsoruibal.com/slides/android2gwt/

Thanks Google, GDG Barcelona and GDG Tarrragona for the organization of such great event!


Java vs C# vs Javascript 5

*** UPDATE: This article had a HUGE mistake in the Javascript part, read below ***

I’m a Java guy but I’m always opened to other programming languages. I heard great things about Mono and the .Net platform, among those things recently I saw a Xamarin article about Android being ported over Mono in a project called XobotOS (http://blog.xamarin.com/2012/05/01/android-in-c-sharp/) and they are getting a much better performance than with Dalvik.

They did it using Sharpen: an automated tool that can convert from Java source code to C#. I was hesitated and started to port my “Carballo” chess engine to C#. Sharpen runs as an eclipse plugin (but outside eclipse). The best tutorial that I found to install sharpen is here: http://www.pauldb.me/post/14916717048/a-guide-to-sharpen-a-great-tool-for-converting-java

The new Carballo Chess Engine with a C# version is now hosted at GitGub (https://github.com/albertoruibal/carballo). You can launch the conversion tool running “ant” on the “csharp/” folder. This C# version hasn’t a graphic interface yet, but is great to make some comparisons…

I use a lot the BT2630 chess test suite, with positions to find the best move, lets see how much time needs my chess engine in Java to find the solution for the first position:

r q . . r . k . 8
. . . . . p p . 7
p . . . . . . . 6
. . . . b N P . 5
. p . . P . . P 4
. . . . . Q . . 3
P P . . . . K . 2
. . . . . R . R 1
a b c d e f g h white move
DEBUG SearchEngine - depth 1 score cp 170 nodes 176 time 42 nps 4093 pv f3b3
DEBUG SearchEngine - depth 2 score cp 136 nodes 1044 time 123 nps 8419 pv f3b3 b8b7
DEBUG SearchEngine - depth 3 score cp 131 nodes 4335 time 358 nps 12075 pv f1f2 b8b6 f3b3
DEBUG SearchEngine - depth 4 score cp 111 nodes 14603 time 854 nps 17079 pv f1f2 b8b6 f3b3 e8e6
DEBUG SearchEngine - depth 5 score cp 115 nodes 27593 time 1311 nps 21031 pv f1f2 b8b7 h1d1 a8d8 f2d2
DEBUG SearchEngine - depth 6 score cp 119 nodes 50536 time 1450 nps 34828 pv f1f2 b8b7 h1d1 a8d8 f2d2 d8d2
DEBUG SearchEngine - depth 7 score cp 117 nodes 110415 time 1693 nps 65180 pv f1f2 b8b7 h1d1 a8c8 f2d2 b7c6 b2b3
DEBUG SearchEngine - depth 8 score cp 110 nodes 314754 time 2515 nps 125100 pv f1f2 b8b7 h1d1 a8d8 f2d2 d8d2 d1d2 b7c6 b2b3
DEBUG SearchEngine - depth 9 score cp 112 nodes 564320 time 3580 nps 157587 pv f1f2 b8b7 h1d1 a8d8 f2d2 d8d2 d1d2 a6a5 b2b3 b7b6
DEBUG SearchEngine - depth 10 score cp 129 nodes 1219488 time 6174 nps 197487 pv f1f2 b8c7 f3b3 c7b7 b3d5 b7d5 e4d5 a8d8 h1d1 e8e6 a2a4
DEBUG SearchEngine - depth 11 score cp 241 nodes 2430413 time 11373 nps 213681 pv f5g7 e8f8 g7f5 a8a7 f5h6 g8g7 f1f2 b8b5 h6f5 g7g8 f3b3 a7d7 h1c1 d7d1

This is 11.373 seconds at 213.681 nodes per second, my java version is “Java(TM) SE Runtime Environment (build 1.6.0_26-b03)”.

And with Mono? let’s see the result on the same machine:

DEBUG SearchEngine - depth 1 score mate 0 nodes 176 time 25 nps 6769 pv f3b3
DEBUG SearchEngine - depth 2 score mate 0 nodes 1044 time 36 nps 28216 pv f3b3 b8b7
DEBUG SearchEngine - depth 3 score mate 0 nodes 4335 time 58 nps 73474 pv f1f2 b8b6 f3b3
DEBUG SearchEngine - depth 4 score mate 0 nodes 14603 time 136 nps 106591 pv f1f2 b8b6 f3b3 e8e6
DEBUG SearchEngine - depth 5 score mate 0 nodes 27593 time 247 nps 111262 pv f1f2 b8b7 h1d1 a8d8 f2d2
DEBUG SearchEngine - depth 6 score mate 0 nodes 50536 time 450 nps 112053 pv f1f2 b8b7 h1d1 a8d8 f2d2 d8d2
DEBUG SearchEngine - depth 7 score mate 0 nodes 110415 time 813 nps 135644 pv f1f2 b8b7 h1d1 a8c8 f2d2 b7c6 b2b3
DEBUG SearchEngine - depth 8 score mate 0 nodes 314754 time 2058 nps 152867 pv f1f2 b8b7 h1d1 a8d8 f2d2 d8d2 d1d2 b7c6 b2b3
DEBUG SearchEngine - depth 9 score mate 0 nodes 564320 time 3693 nps 152766 pv f1f2 b8b7 h1d1 a8d8 f2d2 d8d2 d1d2 a6a5 b2b3 b7b6
DEBUG SearchEngine - depth 10 score mate 0 nodes 1219488 time 7673 nps 158911 pv f1f2 b8c7 f3b3 c7b7 b3d5 b7d5 e4d5 a8d8 h1d1 e8e6 a2a4
DEBUG SearchEngine - depth 11 score mate 0 nodes 2430413 time 15490 nps 156891 pv f5g7 e8f8 g7f5 a8a7 f5h6 g8g7 f1f2 b8b5 h6f5 g7g8 f3b3 a7d7 h1c1 d7d1

That is 15.490 seconds at 156.891 nodes per second with the “Mono JIT compiler version 2.10.8.1 (Debian 2.10.8.1-3)”.

I didn’t found the Sharp and Mono magic, at least in my case Mono is about a 30% slower than Java. This may be as a result of the automated code conversion…

I tested the GWT part in the GWT Developer Mode. In this mode, the code is run in the server as Java (and not in JS). In recent tests I found that the Javascript version is much more slow, probably because of the GWT Javascript Long emulation (Js does not has 64bits integers).

Well and this chess engine also has a GWT version. GWT is another magical Google product that converts your java code to Javascript. Let’s see how fast runs this test on the browser:

[INFO] [org.vectomatic.libgwtsvgchess] - Main.info(depth 1 score cp 170 nodes 176 time 56 nps 3087 pv f3b3 )
[INFO] [org.vectomatic.libgwtsvgchess] - Main.info(depth 2 score cp 136 nodes 1044 time 186 nps 5582 pv f3b3 b8b7 )
[INFO] [org.vectomatic.libgwtsvgchess] - Main.info(depth 3 score cp 131 nodes 4335 time 483 nps 8956 pv f1f2 b8b6 f3b3 )
[INFO] [org.vectomatic.libgwtsvgchess] - Main.info(depth 4 score cp 111 nodes 14603 time 997 nps 14632 pv f1f2 b8b6 f3b3 e8e6 )
[INFO] [org.vectomatic.libgwtsvgchess] - Main.info(depth 5 score cp 115 nodes 27593 time 1123 nps 24548 pv f1f2 b8b7 h1d1 a8d8 f2d2 )
[INFO] [org.vectomatic.libgwtsvgchess] - Main.info(depth 6 score cp 119 nodes 50536 time 1251 nps 40364 pv f1f2 b8b7 h1d1 a8d8 f2d2 d8d2 )
[INFO] [org.vectomatic.libgwtsvgchess] - Main.info(depth 7 score cp 117 nodes 110415 time 1571 nps 70238 pv f1f2 b8b7 h1d1 a8c8 f2d2 b7c6 b2b3 )
[INFO] [org.vectomatic.libgwtsvgchess] - Main.info(depth 8 score cp 110 nodes 314754 time 2648 nps 118819 pv f1f2 b8b7 h1d1 a8d8 f2d2 d8d2 d1d2 b7c6 b2b3 )
[INFO] [org.vectomatic.libgwtsvgchess] - Main.info(depth 9 score cp 112 nodes 564320 time 4063 nps 138858 pv f1f2 b8b7 h1d1 a8d8 f2d2 d8d2 d1d2 a6a5 b2b3 b7b6 )
[INFO] [org.vectomatic.libgwtsvgchess] - Main.info(depth 10 score cp 129 nodes 1219488 time 7474 nps 163142 pv f1f2 b8c7 f3b3 c7b7 b3d5 b7d5 e4d5 a8d8 h1d1 e8e6 a2a4 )
[INFO] [org.vectomatic.libgwtsvgchess] - Main.info(depth 11 score cp 241 nodes 2430413 time 14216 nps 170951 pv f5g7 e8f8 g7f5 a8a7 f5h6 g8g7 f1f2 b8b5 h6f5 g7g8 f3b3 a7d7 h1c1 d7d1 )

I can’t believe my eyes : 14.216 seconds at 170.951 nodes per second with Google Chome Version 19.0.1084.52… and this is also an automated conversion process…

Yes, in my tests Javascript is faster than Sharpened Mono…