Tuesday, November 30, 2010

Using Boost in Ubuntu with Eclipse

Boost is an open source library of extremely useful and carefully designed C++ classes and methods ranging from graph algorithms, to regular expressions matching, to multi-threading.
Part of the Boost library was also integrated into the C++ standard as the TR1 set of libraries.
You can learn more about Boost here.
Using it with Eclipse in Ubuntu is definitely possible, but not straightforward; so I decided to post this simple tip here, to help folk spare some of the grief.
The first step in using Boost in your code is to download the header (.hpp) files and (optionally) source code - the latest release is 1.45 and is available from Boost's website.
In theory, you could compile it, and build the libraries' binaries yourself: by all means, go ahead and do it, but there is an easier way, if you can live with a slightly 'older' version.

Ubuntu 9.10 (Karmic Koala) comes with Boost 1.34 pre-configured (I think, this is, at any rate, the version that I had on my system):
$ ls /usr/lib/libboost*
/usr/lib/libboost_date_time-gcc41-1_34_1.so.1.34.1
/usr/lib/libboost_date_time-gcc41-mt-1_34_1.so.1.34.1
/usr/lib/libboost_date_time-gcc42-1_34_1.so.1.34.1
/usr/lib/libboost_date_time-gcc42-mt-1_34_1.so.1.34.1
/usr/lib/libboost_filesystem-gcc41-1_34_1.so.1.34.1
/usr/lib/libboost_filesystem-gcc41-mt-1_34_1.so.1.34.1
/usr/lib/libboost_filesystem-gcc42-1_34_1.so.1.34.1
/usr/lib/libboost_filesystem-gcc42-mt-1_34_1.so.1.34.1
/usr/lib/libboost_iostreams-gcc41-1_34_1.so.1.34.1
/usr/lib/libboost_iostreams-gcc41-mt-1_34_1.so.1.34.1
/usr/lib/libboost_iostreams-gcc42-1_34_1.so.1.34.1
/usr/lib/libboost_iostreams-gcc42-mt-1_34_1.so.1.34.1
/usr/lib/libboost_regex-gcc41-1_34_1.so.1.34.1
/usr/lib/libboost_regex-gcc41-mt-1_34_1.so.1.34.1
/usr/lib/libboost_regex-gcc42-1_34_1.so.1.34.1
/usr/lib/libboost_regex-gcc42-mt-1_34_1.so.1.34.1
/usr/lib/libboost_signals-gcc41-1_34_1.so.1.34.1
/usr/lib/libboost_signals-gcc41-mt-1_34_1.so.1.34.1
/usr/lib/libboost_signals-gcc42-1_34_1.so.1.34.1
/usr/lib/libboost_signals-gcc42-mt-1_34_1.so.1.34.1
/usr/lib/libboost_thread-gcc41-mt-1_34_1.so.1.34.1
/usr/lib/libboost_thread-gcc42-mt-1_34_1.so.1.34.1

However, by using Synaptic, you can actually install the more recent 1.40.0 version:


This will install a bunch of libboost_*.so.1.40.0 files into /usr/lib: in order to match the libraries with the header files (and avoid introducing incomprehensible compilation errors at best, and subtle bugs at worst) you should download the matching boost_1_40_0.tar.bz2 from Boost download archives.

We would be almost there, were it not for the fact that the soname does not really comply with the -l gcc linker option.

In gcc the -L option specifies a 'search directory' (this would not be needed, as /usr/lib is searched for libraries by default) and the -l specifies additional dynamic (.so) or static (.a) libraries: you specify the file to include during the link step by omitting the `lib` prefix and the .so or .a extension.
In other words, if your HelloBoost source uses code from Boost Regex (libboost_regex.so) you would specify it like thus:
$ gcc -Wall hello_boost.cc -o HelloBoost -lboost_regex

You can see where I'm heading with all this: the last step will be to add symbolic links that do away with the soname suffixes of Boost libraries, and all will be well:
$ ln -s /usr/lib/libboost_regex.so.1.40.0 /usr/lib/libboost_regex.so

Given that there are in total 24 files for the whole of Boost 1.40, I've done a bit of find & replace magic, and have come up with the following shell file (the other advantage being that, when a later version becomes available for Ubuntu, I will not have to change any of my Eclipse projects setting, but just change the VERSION value in the script):
#!/bin/bash
#
# Simple script to enable Boost with simple -l gcc option
# Use: gcc -Wall hello_world.cc -o HelloWorld -lboost_regex
#
# Created by M. Massenzio, 2010-11-30

VERSION=1.40.0

for libname in libboost_date_time \
            libboost_filesystem \
            libboost_graph_parallel  \
            libboost_graph      \
            libboost_iostreams  \
            libboost_math_c99f  \
            libboost_math_c99l  \
            libboost_math_c99   \
            libboost_math_tr1f  \
            libboost_math_tr1l  \
            libboost_math_tr1   \
            libboost_mpi        \
            libboost_prg_exec_monitor \
            libboost_program_options  \
            libboost_python-py25      \
            libboost_python-py26      \
            libboost_regex            \
            libboost_serialization    \
            libboost_signals          \
            libboost_system           \
            libboost_thread           \
            libboost_unit_test_framework \
            libboost_wave \
            libboost_wserialization 
do
  ln -s /usr/lib/$libname.so.$VERSION /usr/local/lib/$libname.so
done


The last and final step is to tell Eclipse what to look for when building your binary: right-click on your project's folder (in the C++ Perspective, Project Explorer) then Properties > C/C++ Build > Settings, select GCC C++ Linker > Libraries and add the 'stripped' library names in the option list:


Note for the curious: the additional libraries listed there are for Google C++ Unit testing framework, GUnit, available here - you will have to build it, but that's pretty straightforward, resulting in the two libgtest.a and libgtest_main.a libraries - be careful to add those only to your 'Test' configuration and exclude your unit tests from build in your Release/Debug configurations.

Tuesday, November 23, 2010

Using the same model classes in Android, GWT and JPA

These days, it is rather common to have a mobile-enabled web service or application, where you essentially enable your users to access the service both via a browser-enable desktop application, as well as from their mobiles whilst on the go.


It's usually the case that the main business logic, as well as the business Model, are shared between the browser components and your mobile app: however, it is not obvious how to re-use code (or even use the same source code) when you are essentially using two completely separate SDKs, and even different JREs!


In fact, if you are using Google Web Toolkit on the front-end, there's not even a JRE involved: as your classes will be compiled in JavaScript.


This short video shows how you can actually use the very same source files in all three layers, so that when you make changes (fix bugs, add functionality) the improvements are immediately reflected everywhere - and even better, you avoid subtle bugs that may be caused by inadvertently the code going "out-of-sync" in one of the layer.


The example is based on my Android Receipts application, which can also be freely downloaded in Android Market.



Please let me know what you think, and whether you are finding the videos useful - or you prefer the written word!


Update    Someone commented on the low resolution of the video (480p) as making it difficult to follow: I understand, and, in fact, the original video was at a higher res (720x576, 25 fps): unfortunately, uploading to YouTube the resolution gets dropped during the transcoding.
Disappointing, I know, but hardly something I can do anything about.


I would suggest instead to see also Part II of this tutorial, which further elaborates on the topic, and provides some code samples.

Saturday, November 20, 2010

Dump CPU temperature data to a file in Ubuntu

Update: I've figured out that it makes a lot more sense to have a reading of the CPU load to correlate with the temperature reading, so I've added that too using /usr/bin/uptime.

Thursday, November 11, 2010

Changing the value returned by getModuleName

When refactoring the name of the GWT module (which typically involves changing the name of the Module.gwt.xml file, see this post) you also have to change the returned value from getModuleName() in every GWTTestCase:


This is way I usually factor the name of the module out into a utility class, and reference a static constant from every test case: saves a lot of pain and effort following some heavy refactoring.

If you do want to watch the video, here's a few tips:

  • if your connection is fast enough, choose 720p as the resolution, or the various menu items and text in general, will be very blurry;
  • this is best viewed full-screen;
  • a description as to how to create a reusable GWT Module can be found here

Change a GWT Module name

This is really a trivial how-to, but wanted to try out how easy it was to capture Eclipse's window using xvidcap, and then upload to Youtube and embed the video here.


This was all relatively simple (from having the idea, to blog posted and tested, took around 15 minutes) so I plan to do a few more.

If you do want to see the video, here's a few tips:

  • if your connection is fast enough, choose 720p as the resolution, or the various menu items and text in general, will be very blurry;
  • this is best viewed full-screen;
  • do remember if you follow along, and you have unit tests, to change the module name there too (or see this video);

Sunday, November 7, 2010

Implementing a Remote Service in Android - Part I

When I decided that a particular idea of mine could be best implemented as an Android Service, running in the background, I found that there is not much information available on the web, beyond some very basic examples, android.com's API Demo sample, and the AIDL tutorial page.

However, those are rather "sparse" guidelines, and several gaps are left for oneself to fill out by trial and error: so I decided to post this brief how-to, along with the code itself.

As noted in the Android Developer's guide:

A service doesn't have a visual user interface, but rather runs in the background for an indefinite period of time. For example, a service might play background music as the user attends to other matters, or it might fetch data over the network or calculate something and provide the result to activities that need it. Each service extends the Service base class.

There are actually two ways of implementing a service: one is to just extend the Service class, implement the onBind() method and then implement the Binder interface in your service implementation class (this is the approach described here); the other is to use AIDL (Android Interface Description Language), followed by the API Demo sample (and further described in Part II of this blog - coming soon).

So, here we go: let's assume that we want to implement a simple service, which enables developers to add a simple UI element to their app to allow delighted users to make donations, but freeing them from having to implement all the machinery: our service will take a Developer Key and an Amount value ($ cents), and will credit the amount to the developer's account (we assume that the user's credentials can be retrieved from the system - how to do that is outside the scope of this blog); the app developer herself will only have to implement a simple UI (or a fancy complicated one: that's up to her) and connect to our service.

The service class definition is pretty trivial:
public class DonateService extends Service {
  @Override
  public IBinder onBind(Intent intent) {
    return new DonateServiceImpl(getResources());
  }
}

The service implementation itself is rather simple too:
public class DonateServiceImpl extends Binder { ... }
with all the 'action' being in its onTransact() method:
@Override
  protected boolean onTransact(int code, Parcel data, Parcel reply, int flags) {
    if (code != res.getInteger(R.id.SERVICE_CODE)) {
      Log.e(getClass().getSimpleName(), "Transaction code should be " +
          res.getInteger(R.id.SERVICE_CODE) + ";" + " received instead " + code);
      return false;
    }
    Bundle values = data.readBundle();
    String devKey = values.getString(res.getString(R.string.DEV_KEY));
    int amountInCents = values.getInt(res.getString(R.string.AMT));
    Log.i(getClass().getSimpleName(), getUser() + " wants to donate " +
        amountInCents + " to " + devKey);
    if (amountInCents <= 0) {
      Log.e(getClass().getSimpleName(), "Amount should be a positive integer (" +
          amountInCents + " is not).");
      return false;
    }
    Log.d(getClass().getSimpleName(), "Sending request to server");
    // This is where we would implement our HTTPS connection service, most likely to
    // some RESTful service
    
    return true;
  }

And this is pretty much all there is to it, as far as it concerns to handling a service call (please do read the description on the Service class, as well as the notes about a service's lifecycle: similar to an Activity, there is an onCreate(), onDestroy() etc.) and retrieving the data marshalled by the system, from the calling Activity.

If you now try to 'test' it by using the Android Instrumentation framework from a 'sibling' test project (you create one typically at the same time as you create a new Android project in Eclipse), your code should look something like this:
public void testServiceRuns() {
    Resources myRes = getContext().getResources();
    assertNotNull("The test case resources are null", myRes);
    
    Intent i = new Intent(ACTION);
    IBinder binder = bindService(i);
    assertNotNull(binder);
    
    Bundle values = new Bundle();
    values.putString(myRes.getString(R.string.DEV_KEY), "12345ABCDE");
    values.putInt(myRes.getString(R.string.AMT), 99);
    Parcel data = Parcel.obtain();
    data.writeBundle(values);
    
    try {
      int serviceCode = myRes.getInteger(R.id.SERVICE_CODE);
      assertTrue(binder.transact(serviceCode, data, null, 0));
      Log.i("test", "Service executed successfully");
    } catch (Exception ex) {
      Log.e("test", "Could not transact service: " + ex.getLocalizedMessage(), ex);
      fail(ex.getLocalizedMessage());
    };
  }

Funnily enough, this will work even if you mistype the name of the service's implementation class in the Android Manifest (AndroidManifest.xml):
<application android:label="@string/service_label" 
                     android:icon="@drawable/app_icon">
   <service android:exported="true" 
            android:name=".DonateService"
            android:process=":remote">
      <intent-filter>
         <action android:name="@string/ACTION_DONATE" />
      </intent-filter>
   </service>
</application>

(try changing .DonateService to .blah and this will still work) -- all this to say: the mechanics of Android unit testing are different from a remote invocation, and may succeed even though your service may be unavailable to other applications.

Notice in particular android:process=":remote" - this is what tells Android application manager to lookup your service's intent-filter too, when looking for possible targets, when another process invokes startService(Intent).

Finally, your test case should extends ServiceTestCase - but make sure you change the constructor, from Eclipse's auto-generated one to something like this:

public DonateServiceBinderTest(String name) {
    super(DonateService.class);
    setName(name);
  }
as explained elsewhere.

The <intent-filter> is the trick that does all the magic here: when matched against the Intent's 'action' will cause your service to be invoked.
Which brings us to the next topic: how do we invoke the service from a separately developed, completely independent application?

I have created a very simple Activity (download service_example_usage-0.2_beta from our site) that does exactly that.

In the following, I will largely ignore the niceties of building an Android UI, as these are widely explained elsewhere and are largely outside the scope of this post, and will focus instead on the specifics of calling a Service.

As a general rule, when invoking a Service, you must do it outside of your primary UI thread: for starters, you have no idea how long will it take to complete and, secondly, you want to give the users the ability to terminate it, should it take too long.

Hence:

Rule #1 - execute a service invocation from within a Runnable that executes outside your main UI thread, and set up the service call, so that it has a callback handler;

Which neatly leads to

Rule #2 - to handle the service outcome where this needs to influence changes in the UI (and it most likely will, even for the trivial task of notifying the user that the call succeeded/failed, whatever...) use a Handler, or your app will crash unceremoniously.

Let us dissect the code in SimpleApplication.java (activateService(final int amt)) one step at a time:

1. Visually notify the user that we're engaging in something that will take time to complete, and we aren't quite sure how long:
LinearLayout panel = (LinearLayout) findViewById(R.id.ProgressPanel);
    panel.setVisibility(View.VISIBLE);

the progress bar has been defined in the layout/main.xml file as 'indeterminate' and as a spinning wheel:
<ProgressBar android:id="@+id/ProgressBar" android:layout_height="wrap_content" 
                android:layout_marginLeft="15px" android:layout_width="wrap_content"
                android:indeterminate="true" android:indeterminateBehavior="repeat" 
                android:visibility="visible"/>

2. Create an intent, whose action will match the service's action's intent-filter (see note below[*] regarding sharing common strings between the service and its intended users):
Intent i = new Intent(getResources().getString(R.string.ACTION_DONATE));

3. Using this Activity's Context, bind it to a service that can service this Intent, by providing an implementation of a ConnectionService interface:
boolean isConnected = bindService(i, new ServiceConnection() {
     @Override
     public void onServiceConnected(ComponentName name, IBinder service) {
       Bundle values = new Bundle();
       values.putString(getResources().getString(R.string.DEV_KEY),
           getResources().getString(R.string.DEVELOPER_KEY_VALUE));
       values.putInt(getResources().getString(R.string.AMT), amt);
       Parcel data = Parcel.obtain();
       data.writeBundle(values);
       boolean res = false;
       try {
         res = service.transact(serviceCode, data, null, 0);
       } catch (RemoteException ex) {
         Log.e("onServiceConnected", "Remote exception when calling service", ex);
         res = false;
       }
       Message msg = Message.obtain(h, serviceCode, amt, (res ? 1 : -1));
       msg.sendToTarget();
     }

     @Override
     public void onServiceDisconnected(ComponentName name) {
     }
   }, Context.BIND_AUTO_CREATE);

4. Wrap the above into a Runnable, and then kick the Thread alive:
Thread serviceThread = new Thread(new Runnable() {
     @Override
     public void run() { //... }
   });
   serviceThread.start();

5. To enable this newly created thread to 'callback' your activity and carry out tasks inside the UI thread, you need to implement a Handler class, create a Message to wrap your returned results and then configure your handler as the message's target:
// outside the Runnable:
  final Handler h = new ServiceCompleteHandler(result, panel, ctx);
// this will be invoked inside the UI thread when called
// at the end of onServiceConnected, in the service activation thread
  Message msg = Message.obtain(h, serviceCode, amt, (res ? 1 : -1));
  msg.sendToTarget();

Your Handler needs to override the default handleMessage() method (that does nothing otherwise) and will be run by the System inside your UI thread (and will thus have access to your Activity's widgets, without causing a RuntimeException):
public static class ServiceCompleteHandler extends Handler {
  @Override
  public void handleMessage(Message msg) {
    int amt = msg.arg1;
    boolean outcome = msg.arg2 > 0;
    serviceComplete(amt, outcome);
  }

  void serviceComplete(int amt, boolean outcome) {
    panel.setVisibility(View.INVISIBLE);
    Rect r = new Rect(0, 0, 48, 48);
    Drawable icon;
    if (outcome) {
      icon = getResources().getDrawable(R.drawable.accepted_48);
    } else {
      icon = getResources().getDrawable(R.drawable.cancel_48);
    }
    icon.setBounds(r);
    result.setCompoundDrawables(icon, null, null, null);
    int dollars = amt / 100;
    int cents = amt % 100;
    result.setText(getResources().getString(outcome ? 
        R.string.thanks : R.string.sorry) + dollars +
        "." + cents + "\n" + getResources().getString(R.string.promo));
    result.setVisibility(View.VISIBLE);
  }
}

And this is pretty much all there is to it: sure, it's a bit more convoluted than just invoking a method in class, but we're talking here inter-process communication (IPC) and remote invocation (RMI) and they ain't pretty in any of the other frameworks either (think J5EE or, God forbid, CORBA).

In a subsequent post, I will show how to use AIDL to make invoking the service a more painless experience for the clients, but at the cost of having a slightly more convoluted development process on the service implementation's side.
---
[*]A note about re-using common strings (see the file res/values/donate_service_strings.xml): it is good practice not to use hard-coded strings in your service calls and data maps, and even better to have them in a commonly shared file (instead of duplicated everywhere in each applications strings.xml file).

Ideally, if you publish a service, you should make such a file freely available to your service users (eg, downloadable from your API docs site's pages); equally, if you use a service, either use the available strings file (hopefully made available from your provider -- if they don't, question your desire to use their service...) or partition those service-specific strings in its ownd dedicated file.

Eclipse users: while developing your service, you will certainly want to test it out with a simple app (very much like I describe here). The obvious way to heed the above advice would then be to add the 'strings' file as a "link" in Eclipse Package Explorer, so that any changes made during the service development, would be automatically picked up the 'testing' app.

This won't work (Android's plug-in does not pick linked .xml files in the res/... tree, to generate the R.java file). A simple workaround would be to create a soft link to the one file in the res/values/ directory:
$ ln -s ../DonateService/res/values/donate_service_strings.xml res/values/service_defs.xml
(you can give whatever name you wish to the link).
In the downloadable code, I've added a physical copy to the file in each package, to avoid people having troubles when re-using it: if you do use both to follow along and/or make changes, I recommend removing one copy and making a link as suggested here.