Mono

Posts related to the Mono Project

IronWatin; mind the gap

Last week @admc, despite being a big proponent of Windmill, needed to use WatiN for a change. WatiN has the distinct capability of being able to work with Internet Explorer's HTTPS support as well as frames, a requirement for the task at hand. As adorable as it was to watch @admc, a child of the dynamic language revolution, struggle with writing in C# with Visual Studio and the daunting "Windows development stack," the prospect of a language shift at Slide towards C# on Windows is almost laughable. Since Slide is a Python shop, IronPython became the obvious choice.

Out of an hour or so of "extreme programming" which mostly entailed Adam watching as I wrote IronPython in his Windows VM, IronWatin was born. IronWatin itself is a very simple test runner that hooks into Python's "unittest" for creating integration tests with WatiN in a familiar environment.

I intended IronWatin to be as easy as possible for "native Python" developers, by abstracting out updates to sys.path to include the Python standard lib (adds the standard locations for Python 2.5/2.6 on Windows) as well as adding WatiN.Core.dll via clr.AddReference() so developers can simply import IronWatin; import WatiN.Core and they're ready to start writing integration tests.

Crazysnake; IronPython and Java, just monkeying around

This weekend I finally got around to downloading IronPython 2.6rc1 to test it against the upcoming builds of Mono 2.6 preview 1 (the version numbers matched, it felt right). Additionally in the land of Mono, I've been toying around with the IKVM project as of late, as a means of bringing some legacy Java code that I'm familiar with onto the CLR. As I poked in one xterm (urxvt actually) with IKVM and with IronPython in another, a lightbulb went off. What if I could mix different languages in the same runtime; wouldn't that just be cool as a cucumber? Turns out, it is.

After grabbing a recent release (0.40.0.1) of IKVM, I whipped up a simple Test.java file:

I compiled Test.java to Test.class then to Test.dll with ikvmc (note: this is using JDK 1.6); in short, Java was compiled to Java bytecode and then to CIL:

javac Test.java
mono ikvm-0.40.0.1/bin/ikvmc.exe -target:library -out:Test.dll Test.class

Once you have a DLL, it is fairly simple to import that into an IronPython script thanks to the clr module IronPython provides. It is important to note however, that IKVM generated DLLs will try to load other DLLs at runtime (IKVM.Runtime.dll for example) so these either need to be installed in the GAC or available in the directory your IronPython script is running in.

Here's my sample test IronPython file, using the unittest module to verify that the compiled Java code is doing what I expect it to:

When I run the IronPython script, everything "just works":

% mono IronPython-2.6/ipy.exe IkvmTest.py  
.
----------------------------------------------------------------------
Ran 1 test in 0.040s

OK
% 

While my Test.java is a fairly tame example of what is going on here, the underlying lesson is an important one. Thanks to the Mono project's CLR and the advent of the DLR on top of that we are getting closer to where "language" and "runtime" are separated enough to not be interdependent (as it is with CPython), allowing me (or you) to compile or otherwise execute code written in multiple languages on a common (language) runtime.

That just feels good.

Toying around with ASP.NET MVC and NAnt

I recently found myself toying around with a number of web frameworks (like Seaside) to get a good read on who's doing what in the web world outside of Python and Django, when I stumbled across the ASP.NET MVC Add-in for MonoDevelop. Though the new Vim keybindings are sweet, I still can't effectively get work done in MonoDevelop yet. What MonoDevelop does do however is support generating Makefiles for any given project, which allowed me to create some Makefiles for an ASP.NET MVC project I had created in MonoDevelop, and port those Makefiles over to fit my NAnt and Vim-based workflow.

Along with building the necessary DLLs, I prefer to use my NAnt scripts to fire up the NUnit console and fire up a development instance of XSP to test my web applications out. All said and done this fairly basic script does the job; I typically run it with:

nant test run

Not much else to say, hope you find it useful.

Lazily loading attributes.

I found myself talking to Jason today about the virtues of getattr(), setattr(), and hasattr() in Python and "abusing" the dynamic nature of the language which reminded me of some lazy-loading code I wrote a while back. In February I found the need to have portions of the logic behind one of our web applications fetch data once per-request. The nature of the web applications we're building on top of the MySpace, Hi5 and Facebook platforms require some level of network data-access (traditionally via REST-like APIs). This breaks our data access model into the following tiers:

 Dia FTW

Working with network-centric data resources is difficult in any scenario (desktop, mobile, web) but the particularly difficult thing about network data access in the mod_python-driven request model is that it will be synchronous (mod_python doesn't support "asynchronous pages" like ASP.NET does). This means every REST call to Facebook, for example, is going to block execution of the request handler until the REST request to Facebook's API tier completes.
  1. def request_handler(self, *args, **kwargs):
  2. fb_uid = kwargs.get('fb_sig_user')
  3. print "Fetching the name for %s" % fb_uid
  4. print time.time()
  5. name = facebook.users.getInfo(uid=fb_uid)
  6. ### WAIT-WAIT-WAIT-WAIT-WAIT
  7. print time.time()
  8. ### Continue generating the page...

Resurgange of the shell.

Two things happened in such short proximity time-wise that I can't help but thing they're somehow related to the larger shift to interpreters. Earlier this week Miguel introduced csharp shell which forced me to dust off my shoddy Mono 1.9 build and rebuild Mono from Subversion just because this is too interesting to pass up on.

One of my favorite aspects of using IronPyhton, or Python for that matter is the interpreter which allows for prototyping that doesn't involve creating little test apps that I have to build to prove a point. For example, I can work through fetching a web page in the csharp shell really easily, instead of creating a silly little application, compiling, fixing errors, and recompiling:

  1. tyler@pineapple:~/source/mono-project/mono> csharp
  2. Mono C# Shell, type "help;" for help
  3.  
  4. Enter statements below.
  5. csharp> using System;
  6. csharp> Console.WriteLine("This changes everything.");
  7. This changes everything.
  8. csharp> String url = "http://tycho.usno.navy.mil/cgi-bin/timer.pl";
  9. csharp> using System.Web;
  10. csharp> using System.Net;
  11. csharp> using System.IO;
  12. csharp> using System.Text;
  13. csharp> HttpWebRequest req = HttpWebRequest.Create(url);
  14. <interactive>(1,17): error CS0266: Cannot implicitly convert type `System.Net.WebRequest' to `System.Net.HttpWebRequest'. An explicit conversion exists (are you missing a cast?)
  15. csharp> HttpWebRequest req = HttpWebRequest.Create(url) as HttpWebRequest;
  16. csharp> HttpWebResponse response = req.GetResponse() as HttpWebResponse;
  17. csharp> StreamReader reader = new StreamReader(req.GetResponseStream() as Stream, Encoding.UTF8);
  18. <interactive>(1,45): error CS1061: Type `System.Net.HttpWebRequest' does not contain a definition for `GetResponseStream' and no extension method `GetResponseStream' of type `System.Net.HttpWebRequest' could be found (are you missing a using directive or an assembly reference?)
  19. csharp> StreamReader reader = new StreamReader(response.GetResponseStream() as Stream, Encoding.UTF8);
  20. csharp> String result = reader.ReadToEnd();
  21. csharp> Console.WriteLine(result);
  22. <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final"//EN>
  23. <html>
  24. <body>
  25. <TITLE>What time is it?</TITLE>
  26. <H2> US Naval Observatory Master Clock Time</H2> <H3>
  27. <BR>Sep. 11, 07:29:02 UTC
  28. <BR>Sep. 11, 03:29:02 AM EDT
  29. <BR>Sep. 11, 02:29:02 AM CDT
  30. <BR>Sep. 11, 01:29:02 AM MDT
  31. <BR>Sep. 11, 12:29:02 AM PDT
  32. <BR>Sep. 10, 11:29:02 PM AKDT
  33. <BR>Sep. 10, 09:29:02 PM HAST
  34. </H3><P><A HREF="http://tycho.usno.navy.mil">Time Service Department, US Naval Observatory</A>
  35.  
  36. </body></html>
  37. csharp> reader.Close();
  38. csharp> response.Close();
  39. csharp>

NAnt and ASP.NET on Mono

Most of my personal projects are built on top of ASP.NET, Mono and Lighttpd. One of the benefits of keeping them all running on the same stack (as opposed to mixing Python, Mono and PHP together) is that I don't need to maintain different infrastructure bits to keep them all up and running. Two key pieces that keep it easy to dive back into the the side-project whenever I have some (spurious) free time are my NAnt scripts and my push scripts.

NAnt
I use my NAnt script for a bit more than just building my web projects, more often than not I use it to build, deploy and test everything related to the site. My projects are typically laid out like:

  • bin/ Built DLLs, not in Subversion
  • configs/ Web.config files per-development machine
  • libraries/ External libraries, such as Memcached.Client.dll, etc.
  • schemas/ Files containing the SQL for rebuilding my database
  • site/ Fully built web project, including Web.config and .aspx files
  • sources/ Actual code, .aspx.cs and web folder (htdocs/ containing styles, javascript, etc)

Executing "nant run" will build the entire project and construct the full version of the web application in the site/ and finally fire up xsp2 on localhost for testing. The following NAnt file is what I've been carrying from project to project.

  1. <?xml version="1.0"?>
  2. <project name="MyProject" default="library" basedir=".">
  3. <property name="debug" value="true" overwrite="false" />
  4. <property name="project.name" value="MyProject"/>