Hello Android Studio

I have installed Android Studio, and I have made a Nexus 7 ready to be used as target device. Now I am ready to develop a first "Hello world" application.

Android Studio make it very easy.

Just select New Project from the file menu (or from the welcome dialog) and specified which properties you want to change from the default schema. I modified just three of them:
- Application name: Hello Android
- Module name: HelloAndroid
- Package name: dd.HelloAndroid
Then was just a matter of compiling and, after ensuring the target device was connected and available to my developer unit, ran it.

After confirming on Nexus that I wanted to debug that app, I saw it appearing. It doesn't say much. It just have the "Hello Android" name on the title bar and, wait a moment, an "Hello world!" message below it? Where does it come from?

We should remember that among the properties we were asked to confirm to create a new project, there was also something about the layout to be used by the application. Let's check it.

I opened the Project View, I clicked on my HelloAndroid project, src, main, res, layout, and I finally see it, activity_main.xml.

In it I see that the TextView property is filled with an @string/hello_world. So I opened the res, values, strings.xml, and I saw that a hello_world string resource was set for me to the value "Hello world!"

I don't want any message on my app, so I cut that line, went back to activity_main.xml, and remove from the "text" property the reference to that string. Re-launching HelloAndroid I can now enjoy its beautiful emptiness.

Go to the full post

Setting up Nexus 7

I have downloaded and set Android Studio up, now I have to decide against which target I want to run the applications that I develop. Actually, we are not forced to use a real device, we could also using an emulation. Still, having at hand a Nexus seven, it looks kind of a good idea to use it.

To be allowed to use Nexus 7 as a developer tool, you need to activate the developer options.

In the settings page, look in the system section, and click on the "about tablet" item.
Tap seven times (I'm not kidding) on "build number" and ... now you are a developer!

That means that when you go back to settings page, you can see in the system section he Developer options. Click on that item, you enter the Developer options page, where you find, in the Debugging section, the USB debugging option, that you should activate.

Now, if you run the command
adb devices
You should see that "something" is available.

Back to Android Studio, once you are in a project, you can open the Run menu, where you'll see the Edit Configuration... item, clicking on which, you will also be able to determine the target device. You can choose an Emulation (you have to specify which device you want to emulate) or you can specify that you want to use an USB device.

Go to the full post

Setting up Android Studio

Android Studio is the Google IDE for Android based on Intellij IDEA announced at 2013 Google I/O. Currently is available in an early access preview that, even if not completely stable, is worth a try.

Here I report what I have done to install it on a Linux Debian-based (actually Ubuntu) box, then I'll write about how I developed a first "Hello world" application.

Download

On android.com, I went to the Android Studio page. There I found links to specific Android Studio bundles for three different platforms, Windows, Mac OS X, Linux. I clicked on the Linux one, and I patiently waited the 400 Meg package to be downloaded on my machine. At the time I have written this post, the current version was 0.2.2.

Install

The bundle was actually a compressed tarball, named "android-studio-bundle-130.737825-linux.tgz". I moved it to someplace looked right to me, and expanded it by a call to tar xvfz. Anything was put in the folder android-studio. Under its bin directory there is a shell script, studio.sh, that we need to call to run the IDE.

Theoretically speaking, that's it.

Still, I have experience a couple of issues. The minor one was solved installing Gradle "by hand", getting it from the official gradle.org download page. The other came from adb, the Android Debug Bridge, that had a couple of dependencies not resolved at runtime. It logged that the problem was about curses, but when I ran ldd on it, I saw that where reported as not found both libncurses.so.5 and libstdc++.so.6. In my case this was due to the fact that I am on a 64 bit system, while adb is a 32 bit application. This was the solution:
sudo apt-get install lib32ncurses5 lib32stdc++6

Go to the full post

Introduction to ActiveMQ

Sort of mouthful of a title for this book, Instant Apache ActiveMQ messaging application development how-to, but don't let this taking you aback. It is a slim (sixty-sh pages) tutorial on ActiveMQ written by Timothy Bish, who actually is an active contributor to that Apache project.

You can't expect it to go too deep in the matter, after all it's in a series that has as headline "Learn in an instant, short, fast, focused", still it I think it is good as a first tutorial. It refers ActiveMQ version 5.8 (the latest release, currently), and it is thought for a Java developer who needs to get introduced to this message broker. You'd better to have some experience on Java, but you'd probably get the most of it even if you don't know much about MOM (Message-Oriented Middleware) and in particular about JMS, the Java EE messaging standard defined by the JSR 914 specification and implemented by ActiveMQ.

After installing ActiveMQ and setting up a working environment (no IDE is used, we are showed instead how to do it "by hand", via Maven), it is showed how to create a first simple application that sends and receive a message. Then we are introduced to JMS queues, topics, selectors. All this stuff is marked as "simple", and it is followed by a chapter where we are introduced to the request-response pattern (the only part of the book that is considered "intermediate").

The third part of the book consists in half a dozen "advanced" chapters where we can read about scheduling, monitoring, testing, pooling connections, using virtual destinations and failover transport.

Lot of examples help to make clearer the concepts explained by Bish in a plain and readable prose. There is no room to enter in much details, still many "There's more" sections offer pointers to find more information in the net.

Go to the full post

Marshalling derived classes with JAXB

When I have to convert Java objects to XML strings, I normally use JAXB, the nice standard library included in the Java Standard Edition since version 1.6. I have already written in the past about marshaling and unmarshaling (that means, transform an object to an XML stream, and vice-versa), but I have recently used JAXB to marshal a class that has a polymorphic data member. There are a few differences from the standard behavior that I think they deserve some extra words.

I have a hierarchy of classes, that I want to use polimorphically in another class. Something like this:
@XmlRootElement // 1
public class Data {
  @XmlElement
  private String a;

  // ...
}

@XmlRootElement 
public class DataExt extends Data {
  @XmlElement
  private String b;

  // ...
}

@XmlRootElement
public class Phone {
  @XmlElement
  private String type;
  @XmlElement // 2
  private Data data;

  // ...
}
1. This is not enough. When JAXB performs the binding, it doesn't care about the runtime class associated to the current object, but it goes straight to the compile time type. We should explicitly say which other classes are part of the hierarchy, using the XmlSeeAlso annotation.
2. We need also to tell to JAXB that it should check the runtime type for this object. This is done by replacing the XmlElement annotation with @XmlElementRef. Actually, at least in my case, this is not a strict necessity. Once specified @XmlSeeAlso on the class definition, JAXB is smart enough to deduce that it has to polimorphically treat the related objects. Still, it adds an attribute to element, in my case xsi:type="dataExt", to show which is the actual type it is using.

So, we'd better change an annotation, and add another one:
@XmlRootElement
public class Phone {
  @XmlElement
  private String type;
  @XmlElementRef
  private Data data;

  // ...
}

@XmlRootElement
@XmlSeeAlso(DataExt.class)
public class Data {
  @XmlElement
  private String a;

  // ...
}
Besides, I also wanted to keep transparent to the XML user which kind of actual class I used. Meaning that I want the same tag for elements referring to the Data hierarchy. That's very easy. I specify the same name for both XmlRootElement's:
@XmlRootElement(name="data")
public class DataExt extends Data {
  @XmlElement
  private String b;

  // ...
}

Go to the full post

Improved SLF4J simple logging

I have written in the past a few introductory posts to SFL4J based on version 1.6.4 that are now obsolete (as Peter correctly pointed out). Here I consider mainly that, since version 1.6.6, SLF4J SimpleLogger supports configuration properties. This makes more attractive the SimpleLogger usage, at least for a tiny project, or for early stages of development.

The process of installing SLF4J has not changed at all in this time, you should go to the official SLF4J download page, fetch the latest package available (currently version 1.7.5), extract the content in your preferred local directory. If, for any reason, you need a previous version, you could go and fetch it from the SLF4J repository.

I have written a tiny two-class Java application to check logging at work. The main class, named Hello, does some logging and then create an object of the other class (that I named Another):
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class Hello {
  public static void main(String[] args) {
    Logger logger = LoggerFactory.getLogger(Hello.class);

    logger.info("an info message");
    try { Thread.sleep(472); } catch(Exception e) {}
    logger.error("an error message");
    try { Thread.sleep(123); } catch(Exception e) {}
    logger.trace("a trace message");
    try { Thread.sleep(42); } catch(Exception e) {}
    logger.warn("a warn message");
    try { Thread.sleep(105); } catch(Exception e) {}
    logger.debug("a debug message");

    new Another();
  }
}

The other class, Another, is even simpler:
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class Another {
  public Another() {
    Logger logger = LoggerFactory.getLogger(Another.class);
    logger.info("an info message");
    logger.error("an error message");
  }
}

To build these classes, you need to put in classpath the SLF4J API jar, named slf4j-api-1.7.5.jar (version number may vary).

The minimal configuration to run my application requires to see the same SLF4J API jar in its classpath. Forgetting it leads to a java.lang.NoClassDefFoundError for org/slf4j/LoggerFactory. Otherwise you would get a friendly warning from SLF4J, that could be translated "You didn't say where I should send your log, so I would just swallow your messages, sending them to the NO-OP plugin. If this is not the behavior you expected, you'd better check the documentation":
SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".
SLF4J: Defaulting to no-operation (NOP) logger implementation
SLF4J: See http://www.slf4j.org/codes.html (...)
And if you check the documentation, you would see that you have to put in the classpath another jar, that would determine how the logger should behave.

The NOP implementation is contained in slf4j-nop-1.7.5.jar, if you put this jar in the classpath, you will get the same result as above (nothing logged), without the showed reminder.

If you want SLF4J to delegate to JUL the logging, you should put slf4j-jdk14-1.7.5.jar in the classpath. JUL is the standard Java Logger, (java.util.logging is its package name), included in the JDK since version 1.4, and the SLF4J plugin used in this case acts as a bridge to that log implementation. For my example, I get this output:
Apr 19, 2013 8:18:45 PM Hello main
INFO: an info message
Apr 19, 2013 8:18:46 PM Hello main
SEVERE: an error message
Apr 19, 2013 8:18:46 PM Hello main
WARNING: a warn message
Apr 19, 2013 8:18:46 PM Another 
INFO: an info message
Apr 19, 2013 8:18:46 PM Another 
SEVERE: an error message

Let's finally see what I get if I put in the classpath slf4j-simple-1.7.5.jar, the SLF4J simple logging plugin.
[main] INFO Hello - an info message
[main] ERROR Hello - an error message
[main] WARN Hello - a warn message
[main] INFO Another - an info message
[main] ERROR Another - an error message
In square brackets we have the thread name, then we see the log level, then the logger name, and finally the log message.

The interesting part is that now we can specify a file, named simplelogger.properties, where we could set some configuration variables. More details in the official SLF4J documentation, but let's see a sample configuration file, and which is its impact on the log generation:
#default is System.err
#org.slf4j.simpleLogger.logFile = simple.log

#trace, debug, info, warn, error - default is info
org.slf4j.simpleLogger.defaultLogLevel = trace

org.slf4j.simpleLogger.log.Another = error

#default is false
org.slf4j.simpleLogger.showDateTime = true

#default is milliseconds since startup
org.slf4j.simpleLogger.dateTimeFormat = HH.mm.ss:SSS

#default is true
org.slf4j.simpleLogger.showThreadName = false
If we specify the org.slf4j.simpleLogger.logFile property, the log is redirected to the file named in that way. By default the special name System.err is used, that is a placeholder for the standard error console.

The default loglevel is info, meaning only info and above are usually logged, but we can change it setting the org.slf4j.simpleLogger.defaultLogLevel property. Here I say that I want to see all the logging (being trace the lowest available level).

I can set the loglevel for a specific class (or package), setting a org.slf4j.simpleLogger.log.* property. Here you can see that for the class Another I want to dump only the top level log messages (namely, errors).

Usually date/time is not shown in the log, to have it we should specify that org.slf4j.simpleLogger.showDateTime is true.

If we don't specify the date/time format, and we specify that we want it showed, we see the number of milliseconds from the application startup. The org.slf4j.simpleLogger.dateTimeFormat is used to specify a different format. Here I ask for the its time as hour-minute-second:milliseconds.

If I don't care of the thread name, I can say that I don't want it to be logged, setting the org.slf4j.simpleLogger.showThreadName to false.

With such a simplelogger.properties, the resulting log is something like:
20.51.11:015 INFO Hello - an info message
20.51.11:488 ERROR Hello - an error message
20.51.11:612 TRACE Hello - a trace message
20.51.11:654 WARN Hello - a warn message
20.51.11:760 DEBUG Hello - a debug message
20.51.11:761 ERROR Another - an error message

Go to the full post

History for Ajax pages

If you write dynamic JavaScript web pages you know about the nuisance of not having the browser managing back and forward buttons for your code. There is a number of solutions to overcome this issue, in my team we tested a few of them, than we shortlisted the candidates to history.js and backbone.js, and I think we are about to use the latter.

If you need some background on the matter, you could have a look at these pages:
Mark Pilgrim put on the web some material from his book on HTML5, here is a chapter on the history API
On Google Developers, a getting started document on Ajax crawling
On the Mozilla Developer Network, an article on Manipulating the browser history
A description of the solution provided by history.js is available on github.
Also on github you can get information on backbone.js.

The point is that we can't just rely on the HTML5 solution, the so called History API (or pushState), because we should support also clients that are using older browser. Before pushState, a few indipendent solutions were designed to tweak the fragment identifier support offered by HTML4, see this page on w3.org for details, to achieve the same result. What history.js, backbone.js, and others do is providing a way to keep the code specific to each platform localized in a place.

I am going to create a simple tiny web page with history support provided by backbone.js, and to do that I need to have at hand a couple of libraries, actually, three of them: jQuery, underscore.js, and backbone itself.

The changes to my pages are driven by three links, each of them generating an event, which should result on setting some text in a div. Admittedly, nothing fancy. But bear with me.

The HTML would be something like this:
<div id="msg">Hello backbone</div>
<hr />
<p><a href="#event/id/3">Event id 3</a></p>
<p><a href="#event/id/5">Event id 5</a></p>
<p><a href="#event/id/7">Event id 7</a></p>
The interesting part is the JavaScript code, just a couple of (dense) lines:
new (Backbone.Router.extend({ // 1
  routes: { "event/id/:id": "processEvent" }, // 2
  processEvent: function(id) { $('#msg').text('Event id ' + id); } // 3
}));

Backbone.history.start(); // 4
1. An object is created here. It is an Backbone.Router extended by the object passed, that contains two properties.
2. This routes property is used to route the event generated by the user JavaScript to what it should do. Going to the backbone router we could delegate to it the job of taking care of the history. What we say to backbone here is to get each link in the format "event/id/" plus a parameter and call a function with the name specified as value (here I've chosen the name "processEvent").
3. The name of the second property should match with the value in the object defined above (I mean, "processEvent"), and its value is the function that I want to be executed by the backbone router on my request. Here I get the div with id msg, and I set its text to a different string accordingly to the passed parameter.
4. I'm ready, so I ask backbone to start the history.

Now what happens is that clicking on the link the user changes the page content and its URL in the address bar. The browser history will work fine, and we can copy the page URL, and open it in a different browser to get the expected behavior.

Go to the full post