Project Linker for Xamarin Studio

When working in C# projects that target multi plataforms and need to have a high code reuse ration, like those that must run on iOS, Android, Windows Phone and any other desktop platform where .NET might run (Windows itself, Linux and Mac) it is common to face a problem: how to share code between the different projects, while maintaining your sanity?

PCL (Portable Class Libraries) is a possible solution, however it is a fairly new feature even in Visual Studio (it is fully supported starting in the 2012 version), and Xamarin Studio / MonoDevelop still have some heavy work to do. Also, PCL imposes some restrictions on what you are allowed to do as well.

One common approach is to have a “Core” project that targets the full .NET framework, and a series of “Linked” projects with compiler flags specific to each platform. This is very well described at the page “Sharing Code Options” at Xamarin’s website. However, do that by hand is not productive and error prone. Visual Studio users can make use of a extension, but how about Xamarin Studio?

Wait no more, now it is possible to do project linking in Xamarin Studio / MonoDevelop as well, with the Project Linker extension I created.

This addin was developed in order to automatically create and maintain links from a source project to a set of target projects, in order to make code sharing between different plataforms a more friendly task. It is based on the Visual Studio Project Linker extension.

The main reason behind the development of this addin was that I was working on a project that targets multiple plataforms using the great MvvmCross library, including iOS, Android, Windows, Mac and Linux, and PCL support was very lacky on Xamarin Studio, and even on Visual Studio 2012 it had its problems. Also, PCL programming imposes some restrictions that I found harder to workaround than using a third party plugin to do the file linking between the projects.

Features

  • Automatically replicates “new”, “delete” and “rename” operations from the source to the target projects
  • Allows to perform a manual synchronization, which is useful if you use both Visual Studio and Xamarin Studio or if someone else does not have the plugin and changes the project
You can install the extension directly from within Xamarin Studio, with the “Addins manager” tool. More instructions and information you can find at http://rafaelsteil.github.io/monodevelop-project-linker/

Zero downtime deploy script for Jetty

One of the challenges when developing Java web applications is to deploy new versions of the app without any perceptible downtime by the end users – in fact, this impacts virtually any platform, although in Java it could be trickier than for PHP or Rails, for example. The problem is that most servlet containers need to first shutdown the context in order to load it again, an operation that can take several seconds to complete (or, in a worst scenario, several minutes, depending of how your webapp is built).

When you have a cluster of servers serving the same app it may not be such a big problem, as one possible approach is to deploy the new version one box at a time. On the other hand, it is fairly common to have a single machine (despite its size) with a single webserver to do all the work, and there lies a monster.

In order to address such issue, I have created a bash script that does some tricks with Jetty and Apache configuration files that allows us to deploy a new version of the application and switch to it (as well switch back to the older version if necessary) with no noticeable downtime. Although it was created with the environment we have in production there where I work in mind, it is easy to adapt it to your needs (or vice-versa). The script assumes the following:

  • Jetty’s hot deploy feature should be disabled (basically, set “scanInterval” to 0 in jetty-contexts.xml)
  • Apache is in front of Jetty through mod_proxy
  • Your app is deployed as an open directory (e.g, not as a war), ideally using Capistrano or another similar tool
  • The ports 8080 and 8081 are available
  • The environment variable JETTY_HOME points to the Jetty installation directory
  • The environment variable APACHE_HOST_CONF points to the Apache configuration file for the host you are dealing (ideally not httpd.conf, but “example.conf”)
It works this way: you use the script “jetty_deploy.sh” as workhorse in place of the usual “jetty.sh”. To start a new instance, run “jetty_deploy.sh start_new”, and the script will change the proper configuration files to listen on the “opposite” port (e.g, 8081 if 8080 is the current one, or vice-versa), start a new Jetty server and wait until the context fully starts. After that it will restart Apache, which will then proxy all requests to the new jetty server. If something goes wrong you can use “jetty_deploy.sh rollback”, and if everything is OK, you can stop the previous and old instance by running “jetty_deploy.sh stop_previous”. Simple as that.
The project is freely available at https://github.com/rafaelsteil/jetty-zero-downtime-deploy, and please make sure you read the instructions in the file “jetty_config”. In fact, it is advisable to either understand how “jetty_deploy.sh” does its job.

Easy and fast XML node access with TBXMLEx

I recently added a very nice feature to one of my Open Source projects, TBXMLEx, which is the possibility of directly access any node without having to loop through all its parent nodes. This is very useful when you know beforehand where the node is located at. The sintax is very clean and concise. Suppose you have the following XML:

NSString *xml = @"<data> \
        <a> \
            <a1/> \
            <a1/> \
            <a1/> \
        </a> \
         \
        <b/> \
        <b/> \
        <c/> \
         \
        <d> \
            <d1> \
                <d11/> \
                <d21/> \
            </d1> \
             \
            <d2> \
                <d21/> \
                <d22> \
                    <d221/> \
                </d22> \
            </d2> \
        </d> \
    </data>";

and that you need to access the “d221″ node, which is pretty deed inside the structure. Using TBXMLEx it is straightforward do to so:

TBXMLEx *parser = [TBXMLEx parserWithXML:xml];
NSArray *result = [parser.rootElement query:@"/d/d2/d22/d221"];
TBXMLElementEx *element = [result objectAtIndex:0];

The key point in the previous code sample is the “query” method (a member of TBXMLElementEx), which takes a path as argument and returns all nodes that matches the criteria, as TBXMLElementEx instances. Right now it supports only simple expressions, but nevertheless it’s a quite useful feature .

You may wonder why not use XPath instead. The point is, while very powerful, you’ll need extra libraries to work with XPath, and it can take some time to master its syntax. The “query” method I implemented does not intend to take over XPath nor reimplement its features, it is just a convenient, syntax sugar method to do regular tasks we face on a daily basis, and while someday it may be improved to be more powerful, XPath will always be the choice when you need to do nasty thigns with XML.

TBXMLEx is an Open Source library freely available at https://github.com/rafaelsteil/tbxmlex