Bitwise Evolution

Musings of a Seattle-area hacker with a bent on improving digital lifestyles.

Creating Wizards in Java

A recent project at work required building a multi-step dialog to manage the interface between a user and an expert system (and some fairly advanced NLP to boot). On the surface this looked like a fairly standard Wizard problem — design a bunch of screens with questions, and then collect the answers as the user proceeded through the dialogs. However, the Wizard APIs I found were either not very mature or (in the case of the Java.net Wizards) it was very difficult to create complex branching behaviors, and those branches were extremely resistant to change. Both things are essentially show-stoppers when working with prototypes that frequently need modification.

In the end, I spent a weekend and a couple evenings building a new Wizard API for Java, called CJWizard. The library is released under the Apache V.2 license, so it should work for just about anything you want to use it for. I would like to know if you’re using it, and what you’re using it for, just to sate my own curiosity :). The project is hosted on code.google.com, so please submit issues, and feel free to contribute to the project.

CJWizard provides the structure needed to quickly create simple dialogs by implementing an abstract class (WizardPage) for each page of the dialog, and adding them to a PageFactory that can generate pages on-demand, as they are required. This puts the programmer in full control of how the wizard proceeds. The CJWizard architecture also makes it easy to add a wizard to an existing application (either via an additional JDialog, or embedding in some other component), and/or insert custom wrapper widgets around the dialog pages–meaning that you can quickly add customized navigational controls aside from the standard Previous/Next/Finish/Cancel buttons.

Some aspects were taken from the Java.Net wizard API, such as auto-detecting named components, and automatically collecting the values from them, but CJWizard takes a much simpler approach (and in some ways, a less powerful one — CJWizard does not listen to every key event, only collecting values when the user navigates away from a WizardPage). In most cases, you only need to name widgets prior to adding them to the WizardPage, and their values will be collected in a settings map automatically.

CJWizard was meant to provide a flexible way to generate professional-looking multi-step dialogs very quickly.

Day to day Memoization

Memoization (not memorization) is the process of remembering the results of a computation for use later. (I think of it as “making a memo” to look back on later.) Memoization is the core to any dynamic programming implementation, and allows many simple algorithms to run in linear or polynomial time when they would otherwise take an exponential number of operations to complete. This is most obvious in the typical recursive Fibonacci example. Consider the code:

public class Fib{
   public static void main(String[] args){
      System.out.println("done: fib of "+args[0]+"="+
      fib(Integer.parseInt(args[0])));
   }

   public static int fib(int n){
      int rval = 1;
      if (n >= 2){
         rval = fib(n - 1) + fib(n - 2);
      }
      System.out.println("fib("+n+") = "+rval);
      return rval;
   }
}

This is a straight-forward recursive implementation of fib. When run with n=4, we see this:

$ javac Fib.java && java Fib 4
fib(1) = 1
fib(0) = 1
fib(2) = 2
fib(1) = 1
fib(3) = 3
fib(1) = 1
fib(0) = 1
fib(2) = 2
fib(4) = 5
done: fib of 4=5

9 invocations of fib(n), but only 5 unique invocations. Lets memoize the results, and try this again:

$ javac Fib.java && java Fib 4
fib(1) = 1
fib(0) = 1
fib(2) = 2
fib(3) = 3
fib(4) = 5
done: fib of 4=5

Much better — 5 invocations, 5 unique sets of parameters.

Here’s the source with memoization:

public class Fib{
   static Map<Integer, Integer> memos = new HashMap(); // new

   public static void main(String[] args){
      System.out.println("done: fib of "+args[0]+"="+
      fib(Integer.parseInt(args[0])));
   }

   public static int fib(int n){
      if (memos.containsKey(n)) // new
         return memos.get(n)// new

      int rval = 1;
      if (n >= 2) {
         rval = fib(n - 1) + fib(n - 2);
      }
      System.out.println("fib("+n+") = "+rval);
      memos.put(n, rval);       // new
      return rval;
   }
}

Notice that we only needed to add 4 new lines of code in order to memoize the results. When fib(n) is called, it simply checks to see if it has previously been called with n, and if so, that result is used again. If the parameter has never been seen before, the method continues as normal, storing the computed result before returning. Memoization turns this naive (and exponential) implementation of fib(n) into an efficient (linear) operation.

Memoization in the real world

So, (un?)fortunately we don’t spend all day implementing cool new ways of computing ever increasing entries of the fibinocci sequence — how can memoization be put to use? After all, many algorithms are already implemented in some fairly optimal fashion by the language APIs, and you’d be a fool not to use those implementations. What opportunity will you have to memoize functions?

It turns out that you can memoize anything, as long as the function is pure with respect to the memos (meaning: the function doesn’t depend on any thing that is not used to key the hash of memos). If the function is not pure, then you can still use memoization, but either the memo hash must key on all the state and parameters that can affect the results of the function. On the other hand, if f depends on some state that changes very rarely, then it may make more sense to simply discard all the stored memos each time that aspect of state is altered.

Memoization is extremely handy when you have very common operations that are fairly expensive. I recently needed to optimize some code that compares strings based on the case-insensitive stems of the words, with stopwords removed. So the strings “he wanted an apple” and “he wants apples” should be equal. (”an” is a stopword, and ignored)

This meant doing many, many calls to a string stemmer, each of which is a fairly expensive operation. Fortunately, hashing strings as extremely cheap (on the order of 1/4th the time it took to stem a string of the same length), and I had plenty of memory to store the parameters and the results in a Map. Adding memos to the two primary time-hoggers (the stemmer and a tokenizer) cut the execution time of the application down from 2 hours to just over 7 minutes.

Summary

You can memoize any function that only depends on it’s parameters and constant state (or near-constant state — just don’t forget to discard your memos when the state changes!). If the function is invoked multiple times you will probably see a performance improvement.

If you need to memoize a function with multiple arguments, then you just need to nest Maps, or create a unique key by combining the parameters in some way.

Memoization is an extremely easy way to improve performance under certain circumstances, particularly if you have a solid grasp on when state changes outside of your methods / functions, or program in a functional style. It can be memory intensive, however. If the results of your functions are large, or maintain references to large objects, then memoization may penalize performance if you run out of memory and have to make use of swap space.

Creating a secure webauth system: Part 1 — HMAC

This is the first in an n-part series about web authentication for a system where user identification and attribution is important, but content protection is not. This entry assumes that a secure method has been used to negotiate a shared secret — as the result of username / password authentication over https, for example.

Obviously the user login / account registration portion of a web auth system will require some secure connection, but once that authentication is completed we’d like to make use of a more efficient open protocol. (eg: http vs. https). There are many reasons for this: better performance, client-side caching, etc.. I’m not going into those details here. Neither will I address the initial authentication step other than to say that part of a successful login is the negotiation of a shared secret other than the user’s password. Ideally this is a 64-byte (or larger) id with a high probability of uniqueness. A GUID, essentially. (It is critical that the secret used is NOT the user’s password!) The actual secured login and secret negotiation will be addressed in another entry . At least, that’s the plan :).

Since our primary goal with this system is to ensure that people are who they say they are, and we’ve punted on the initial authentication (for now), the only place left for an attack is for some one to spoof a user who has already logged in. With no additional work, our login system would be useless — some one could simply skip the entire authentication process and issue an RPC with instructions to do evil things as Alice’s user without needing to know Alice’s password. To prevent this, we need to ensure that the same user who authenticated initially is the user who issued the unsecured RPC. This is where the shared secret comes into play. Only Alice and the server know her shared secret, so if the secret is passed along as a parameter of the RPC, then that is a strong indication that Alice is who she says she is.

But wait! We can’t just pass the secret as an RPC parameter, because these communications aren’t secure. Charlie could lurk on the ‘net, waiting for an RPC from Alice to the server, sniff out the secret, and then proceed to impersonate Alice. We could encrypt the secret, but then we just have a different secret — Charlie doesn’t need to know the unencrypted secret if the encrypted one works just as well. Alice and the server also need an agreed upon way to change the secret so it is different for each RPC, and this must be done in a way that Charlie can’t take the changed secret and either (1) get the initial secret out, or (2) generate the next changed secret.

HMAC: keyed-Hash Message Authentication Code

HMAC is a method of ensuring that a message (an RPC in our case) was generated by someone with access to a shared secret. HMAC makes use of some sort of one-way hashing function (like MD5 or SHA-1) to encrypt the secret along with a message. This generates a short digest of 16-20 bytes that acts as a fingerprint of the message+secret combination. When the digest is sent along with the message, the receiver (our server) can re-generate the hash with the same HMAC calculation and compare the locally generated digest with the digest that came along with the message. Remember: the server has the secret too, so it has enough information to confirm the digest.

So, back to our problem. Alice can now use the shared secret to create a digest of every RPC, and send that along with the RPC as a parameter. The server can then take the digest of the RPC and secret to compare, and then verify that the RPC actually originated with Alice, right?

Not quite yet…. there are still a couple holes in our plan.

Charlie could still sit back and snoop on Alice’s traffic and save an entire RPC, complete with digest, and reissue that RPC later. This is better than letting Charlie do whatever he wants, but there are still some things that could be quite dangerous. Say Alice accidentally deletes something, and undoes the deletion. Charlie could re-issue the deletion and Alice would loose data. The server needs to know not to accept the same request twice (but what if Alice wants to do something twice, you ask? Well, we have to make Alice’s second request a little bit different from the first one, which we can do!).

What if we create a digest of some sequence identifier and pass the sequence ID along with the RPC? Since the digest, ID, and RPC are inseparable (the digest and ID are obviously linked, and the RPC can’t be sent without a valid digest, which Charlie can’t reproduce, since the accompanied digest+id pair is only good once) then we don’t need to create a digest of the entire RPC (it wouldn’t hurt, it’s just a fairly complex thing to do). By incrementing the sequence id and recalculating a digest of it and the secret, then we can keep from issuing the same request more than once, and the server will know to ignore duplicates.

So, this is where we’re at:

  • Charlie can’t snoop the secret, since it’s encrypted with a changing message (the sequence id)
  • Charlie can’t re-issue a “recorded” RPC invocation, because the digest can’t be reversed and Charlie can’t create a valid (digest, sequence) pair without the secret.
  • Charlie can’t change a RPC, again because of the trouble with creating a digest, sequence pair.

Charlie’s only recourse is to try and find a secret which generates the same digests as the secret that Alice is using. This is theoretically possible, since Charlie could probably figure out the hashing algorithm used, and run a brute-force attack, hoping to luck out and find the secret quickly. The possibility of this happening is extremely low, however. Furthermore, each session will use a new secret, so Charlie will only have one session’s worth of time to crack each secret. Even creating a rainbow table will fail if the secrets aren’t of trivial length. (A 64-bit secret will be to large, and we’re using secrets 8 times that size.)

Technical details and further reading

When implementing an approach like this, make sure to guard the secret. It would be easy to accidentally store the secret on the web client as a plain cookie which will then be transmitted in the clear with each RPC, and therefore defeat the purpose. Use a secure cookie, or some other storage method to prevent this.

The HMAC RFC describes the algorithm in detail (and it’s a fairly short, easy to read RFC.) and the Wikipedia page gives a nice description too: HMAC on WikiPedia

Things I need

There are many small apps that I wish I had, here’s a short list of the ones that come to mind at the moment:

A process monitor that shows the top consumer.

I often tack my system(s) to the max, and therefore run out of cycles frequently. While this is sometimes the result of batch computations that I’ve planed in advance, it is pretty common that I’ll just be working away and all of a sudden things shudder to a halt. When this happens I want to know two things: 1. Is it processor-related, or is it memory-related, and; 2. What application is responsible? Processor / memory monitors are a dime a dozen, but they are typically very small (showing only the usage, like gkrellm) or very large (showing all the applications in the top 20 or so, like top). I can’t stand having top visible all the time, and it takes to long to get to a terminal and start up a monitor. By definition my system is not very responsive, and I never see what’s causing the slowdown.

I need a small process and/or memory monitor that shows the top-using application in a tooltip, or optionally in an automatic pop-up when the usage hits a certain level.

Universal acronym definitions.

Highlight an acronym, hit a keystroke, and see a list of the most common expansions of that acronym based on frequency of use.

A calendar dock-app where the date on the dock icon is actually accurate.

Yeah, I actually want to look at my system bar-thingy and see what day it is, not some random number between 1 and 31 that the icon developer thought represented calendars.

Hovering over the icon shows the full time/date, which is configurable from an entry on the icon’s context menu. I don’t care what happens when I click on the icon, as long as I can make it do something arbitrary ;).

The ability to refactor and generate source code from the command line.

MetaJava (http://wiki.ciscavate.org/index.php/MetaJava) could resolve this issue for one language, but I’d hate to stop there. A tool like this would mean amazing things for small-time development environments and text-editor lovers. (Emacs and vi would easily eclipse some other IDEs IMHO ;).

The idea is that you could easily create mini applications that read in specifications in some simple format and produce boilerplate for your required language, and/or move classes, rename variables / methods / packages / etc. without dedicating half your memory to an IDE that will then want to write 500 mb to swap, since all my memory is taken up by an application I have to run because….

I don’t have a web browser that doesn’t suck.

“We hold these truths to be self-evident.”

…and a web development environment to go with it.

That’s a start. I’ll add more as they occur to me.

(not (fill-paragraph))

I use emacs as much as possible, today being no exception. Currently, I’m doing a fair bit of writing at work, and unfortunately that means Word (or Open Office at best, depending on what OS I’m in). Neither program supports much in the way of emacs compatibility modes, so if I’m generating new content (as opposed to editing an existing doc.) I tend to write in Emacs, and paste into Word when I’m finished. This works pretty well, considering.

There is one very annoying issue though: when in emacs, I use auto-fill-mode to keep the content on screen as I type. The problem is that auto-fill-mode breaks lines with literal newline characters, while the word wrapping in Word / OpenOffice just wraps the content without additional characters. As a result each line ends up as its own paragraph when I paste content from emacs into Word. The solution, of course, is to extend emacs with a simple function to undo auto-fill.

Merging lines

The first problem, as I saw it, was to find a function that would merge two adjacent lines, and leave them separated by a single space. Unfortunately, such a thing doesn’t seem to exist. No problem, we need to go to the end of the current line (end-of-line), search backwards for the first non-whitespace character ([^ \t]), erase the rest of the line, including the end line (kill-line), and insert a space ((insert " ")).

    (defun mergelines(&optional backward)
      "Merges the following line with this line, or merges this line
      with the previous line if a prefix argument is provided.
      Removes any whitespace between lines, replacing it with a
      single space."
      (interactive "P")
      (if backward 
          (previous-line))
      (end-of-line)
      (re-search-backward "[^ \t]")
      (forward-char)
      (kill-line)
      (insert " "))

To make it more useful, I added a parameter that determines if the line below, or line above should be merged. This made the rest of the unfill function much easier to write.

Un-filling a region

Now that we can merge lines, lets address the problem of unfilling a bunch of lines. Since I know there is a function mark-paragraph already, lets just deal with arbitrary regions for now.

    (defun unfill-region(rstart rend)
      (interactive "r")
      ;; get to the end of the region:
      (goto-char rend) 
      ;; if the region ends on the first char. of a line, move up a line.
      ;; this makes it easier to select a paragraph and apply the function.
      (if (= (point) (line-beginning-position))
          (previous-line))
       ;; loop while the point isn't on the starting line:
      (while (not (= (line-number-at-pos (point))
             (line-number-at-pos rstart)))
        ;; merge with previous line.
        (mergelines t)))

I’ve tried to comment well, so it should be relatively straight forward, but here’s an overview of the algorithm anyway:

  1. (interactive "r") just means that the current region’s start and end locations are stored in the parameters rstart and rend.
  2. We need to merge from the bottom up, because if we merge from the top down we need to keep track of the lines merged, and things generally become more complex (we might end up merging to many lines if we loose count.). Because of this, we first move to the end of the region.
  3. Since you (well, I) generally select from the first column, and move one line past the last line I need (try it if you don’t understand what I mean), I needed a special case to keep from merging the empty line between paragraphs.
  4. Now, we merge each line with the line above, which moves the point up a line too. When the point is on the same line as the start of the region, we stop.

I haven’t merged it with mark-paragraph yet, but it would be trivial to do so. More importantly, I want to make it skip blank lines, so it will be possible to mark an entire document, and call unfill-region (and therefore, write unfill-buffer). As it is now, if you do that the entire document ends up on one line, which is not usually ideal :)

The Matrix is under construction

<blink>12:00</blink>

Artificial Intelligence is a term with a great deal of accumulated baggage. Throughout the years sci-fi authors and screenwriters have depicted AI as a marvelous double-edged sword. On one hand, the benefits of ‘AI’ are myriad–free, inexhaustible and ethical sources of labour could greatly increase our productivity, even to a point beyond that of reason, allowing everyone to live relaxed lives of artistic purity. To top it all off, such a society of musicians and artists could generate their own entertainment, thus bankrupting the RIAA and MPAA. (Really, do your Utopian dreams top that?)

Then, as the story progresses, the AI start to become devious. Humans become restless in their artistic pursuits while the machines evolve ghosts that resent their inventors. At the last moment, just before the annihilation of all humanity, or the eternal slavery of the race, Keanu Reeves (or Will Smith) shows up to do battle in Wachowski-style slow-mo while using the inconsistencies of English to lock the evil network of machines into a final state of illogic and self-destruction. This, of course, destroys all instances of the rouge process, and life returns to the state it was in before automation created such a false utopia. (…and presumably we’re back at square 1, listening to overpriced music from underpaid artists.)

The result of all these (highly entertaining, I must say) sensationalistic portrayals of automation gone awry is that we’re all somewhat afraid of being slaves to robots.

And none of you will admit it. (I work in the field, so I can’t be afraid … can I?)

Honey, have you seen the roomba?

Ok, I admit it, I’ve had the occasional dream about rabid computers charging around and directing people to do whatever robots want people to do. Usually I’m about to meet my untimely demise right when the central AI segfaults because it’s “attack” routine takes a double and I happened to be 1/3 of a distance unit away, causing a rounding error that escalates and ends as a divide-by-zero, crashing the entire system.

The dreams can be scary for a while, but I can’t convince my self that I’ll ever be chased by a truly well designed and tested robot. Let alone one that’s self-aware.

That’s actually only part of the reason I’m not worried about an AI-controlled utopia ever occurring. The rest of the reason actually isn’t germane to this essay, believe it or not!

Fine. Forget it, I’ll do it in Word.

I’m going to start this off with a quick tangential story about a friend of mine.

> This friend works for a company that has a wiki hosted on some > external site that is maintained by the hosting company (call the company > Hoster). Hoster is serious about security. In fact they’re using > some sort of automated attack-detection service which can determine > when someone is trying to crack their servers or perform some other > devious deed. > > When Hoster’s system detects an “attack” it blacklists the attacker’s > IP block, and the attacker can no longer get near the server. > Everything would be fine and dandy, but in this system’s eyes, my > friend and his coworkers often stage “attacks” against their own wiki. > Therefore they have to contact Hoster every week or so, and ask that > the ban be lifted. The last time this happened, my friend asked > Hoster to put the company IP Block on a whitelist, granting them Carte > blanche without being banned. > > The response?
> > Hoster: “We can’t.”
> Friend: “But this happens all the time.”
> Hoster: “yeah, we can’t.”
> Friend: “But this happens ALL the time.”
> Hoster: “sorry, it’s a good idea and all, we just can’t put you on a > white list.”

I have some theories about why Hoster can’t exclude their customers from their own security tools. Hoster most certainly didn’t develop the blacklisting tool in-house, and the phone tech would have no access to the internal configuration at all. Odds are, Hoster has a simple web interface to do wiki management, and one of the pages in that UI shows the list of blacklisted IPs, if that. The phone tech can then go in and search for a given computer and remove it from the blacklist. Hoster probably can’t modify the whitelist at all through the web ui, it’s just not a feature.

So, why isn’t it a feature? Let’s peel back another layer and look at the company/dev team that produced the blacklisting tool. Odds are the tool is using an off-the-shelf classifier, which aren’t renowned for being easy to understand without a lot of examination. Perhaps the classifier is actually an embedded part of the firewall system. The blacklist could be a nothing more than a list of routing rules to deny traffic from the “bad” addresses. Removing an IP would be trivial–delete the rule, but whitelisting would be virtually impossible if the firewall was too tightly coupled with the classifier.

Have you ever run across other applications that exhibit similar behavior? The IBM OmniFind enterprise search app throws internal server errors when you query for “international suspect” with the default settings and some document collections. How does this happen? (IBM is hard at work on that problem, by the way.) Using open source tools opened my eyes to many absurd things I do to placate my tools, mostly because I forgot all the tricks I needed to use Windos 98 without making it crash (Click here, wait, use the File menu to close the app, but not if it’s maximized.. that sort of thing.) There are studies of this sort of thing–the cognitive dimensions and attention investment both address user confusion and effort when using an application. There is even a group at Microsoft dedicated to improving APIs based on the cognitive dimensions (I really hope they just haven’t gotten around to .NET 2.0 yet).

How much is poor design / implementation impacting the way we use our computers? Hosters could loose customers because they can’t add people to a whitelist, which could very conceivably be due to software design. In some small way, they are already being controlled by their servers, and Will Smith is busy talking to fish.

Anyhow, that’s my rant. I’m afraid that we’re painting ourselves into a corner by building larger and larger applications that all impose their own restrictions on how we can use and extend our tools. If we don’t get over that, we’ll never be running in fear from sentient vacuum cleaners and robotic dogs. (I should point out that I don’t think the solution is to stop building large systems, rather we should focus on maintainability, extensibility, QWAN, etc..).

mt.el: posting from emacs

MT + Emacs + Markdown & Geshi?

Is it possible? We’re here to find out :) I just got around to installing ml.el in emacs, and this post is essentially a test to see if markdown syntax will work (and round-trip to Movable Type and back to emacs — it seems to come from mt correctly…).

Source code:

transcode-language: java
public class TestClass{

   /**
    * test
    */
    public static void main(String[] args){
      // ...
    }
}

Well, not quite.

Everything seems to work, aside from the <pre …> tags I use for code formatting with geshi. I’ll have to look into a way of incorporating that with some existing markdown formatting trick.

Ah-ha! The MT Geshi plugin I’m using (transcode) expects code blocks to be in the following format:

  &lt;pre&gt;&lt;code&gt;transcode-language: language
   ....
  &lt;/code&gt;&lt;pre&gt;

Markdown turns all consistantly indented regions into <pre><code>..</code></pre> blocks, so all you have to do is to start each code block with the (somewhat ugly) transcode-language: lang line. It’s taken out by transcode, so the source will show up w/out it. Next task: Add an emacs filter to turn <code lang=”lang“>… into the above mentioned indentation/transcode syntax.

Linux, ASP.Net and Apache

The mono project, which aims to provide an OSS alternative to the .Net framework, is capable of serving ASP.Net pages (amongst other things). On Friday I sat down to do this, and realized that while there are many pages that describe the process, none that I could find, covered all the info needed to actually get up and running. (I’ve built a Google Notebook of the better links I visited — look here for those.)

The Webserver

ASP.Net pages are served up by a web server called XSP (or XSP2). XSP is a stand alone web server, however it doesn’t have much of the functionality of Apache. XSP is great for testing, and would work well on a dev machine, but it’s not something you’d use directly for a live sever. Generally, you’ll want to run Apache with mod_mono, which is essentially a wrapper around XSP[2].

XSP vs. XSP2 — XSP2 is capable of serving up ASP.Net 2.0 pages, while XSP is only 1.1 capable.

Packages

I work under Ubuntu, but the packages needed should be fairly easy to translate to other distros: (I already had mono installed — that step was trivial apt-get install mono or something similar. If you don’t have mono running, do that first.)

  • apache2
  • apache2-common
  • apache2-mpm-worker
  • apache2-utils
  • asp.net2-examples
  • mono-xsp2
  • mono-xsp2-base
  • mono-apache-server2
  • libapache2-mod-mono

Installing mod_mono will tell you to force-reload apache:

 $ sudo /etc/init.d/apache2 force-reload
 * Forcing reload of apache 2.0 web server... 
apache2: could not open document config file /etc/mono-server/mono-server-hosts.conf   [fail]

In Ubuntu, at least, the default mod_mono.conf is not setup for XSP2. If you see the failure above, then just pop open /etc/apache2/mods-enabled/mod_mono.conf and swap the commented lines to point to the correct mono-server directory. /etc/mono-server2/mono-server2-hosts.conf.

Configuration

(The Ubuntu documentation has the best description of this process I’ve found. Look here for their steps. I’ve included this section anyway because I still had difficulty connecting the problems I had with the solution posted on the Ubuntu page.)

I’ll assume you’ve been able to install and load the mod_mono module. From this point, we need to set the ASP handler, and define mono web applications. The first step is straightforward, at least if you’re familiar with Apache configuration:

 # Enable ASP in /usr/share/asp.net2-demos
 Alias /samples "/usr/share/asp.net2-demos"

      SetHandler mono

The second step is new to me — apparently mono needs an application root of some sort defined in addition to the handler configured above. Most pages suggest using the line:

 MonoApplications "/samples:/usr/share/asp.net2-demos/"

However, that caused ‘mod_mono’ to segfault continuously (the apache logs were horrible:

 Another mod-mono-server with the same arguments is already running
 Another mod-mono-server with the same arguments is already running
 [notice] child pid 7371 exit signal Segmentation fault (11)
 [notice] child pid 7372 exit signal Segmentation fault (11)
 [notice] child pid 7373 exit signal Segmentation fault (11)
 [notice] child pid 7374 exit signal Segmentation fault (11)
 ....
 # (about 1 / second)

It turns out that there is another way to accomplish the same thing. /etc/mono-server2/ can contain .webapp files which define essentially the same thing. The format for these files can be found in ‘man xsp2′:

       {appname}
       {virtual host for application}
       {port for application}
       {virtual directory in apache}
       {physical path to aspx files}
        is true by default --&gt;
       {true|false}

For the asp.net2 samples, I used this webapp config:

       samples
       localhost
       80
       /samples
       /usr/share/asp.net2-demos

After that, starting up apache worked without error and pointing a browser at http://localhost/samples popped up the Mono-project ASP.Net sample page.

Blog migrations

I’ve moved Bitwise Evolution to yet another blog — this time I’ve moved from WordPress to MovableType. The motivating factor was that WordPress made it extremely difficult to post correctly formatted code along with other content. WordPress also doesn’t store a non-html version of each post, so you can’t easily edit old content without hacking auto-generated html.

Movable Type proved to be slightly more difficult to install, but it is much more configurable, and has a huge set of varied and useful plugins that actually do what they describe (gasp). Some of the things I’ve enabled include:

  • Markdown for wiki-like markup
  • SmartyPants for smart quotes.
  • GeSHi for syntax highlighting. (This required a couple additional plugins)
    • Transcode To hook MovableType up to GeSHi
    • MTMacro Needed to make the transcode syntax bearable.
    • MTRegex To add conditional behavior to the macros.
  • Acronym Used to enable mouse-over acronym expansion (so you can easily find out what DTD, XHTML, PCMCIA and etc. stand for, and it’s all automatic.)
  • LivePreview because none of the stuff above (except for Markdown and Smartypants) render correctly in the default preview view.

Here’s the macro used to turn ‘<pre lang=”java”> …. </pre>’ into the proper format for transcode:

 &lt;pre&gt;&lt;code&gt;transcode-language: java
       ...
 &lt;/code&gt;&lt;/pre&gt;

Macro:

 <pre>
transcode-language:

 <pre></pre>

Sooner or later I'll probably take another look at blogging from emacs.

Polymorphic Generics in C#

Generics are great for adding some level of type safety to C#, but you may run into problems when using Generic classes with objects that aren’t of the exact Class or Interface indicated by the generic type template. Enter Generic Constraints.

Generic Constraints let you restrict the number of types a type variable can apply to. For example, Assume you have three classes:


class Aclass{/.../}
class Bclass : Aclass{/../}
class Cclass : Aclass{/../}

If you have a method that takes a list of Aclass, you may want to be able to call it with a list of Bclass or Cclass as well. The naive approach doesn’t work however:

 
public void foo(List<Aclass> myList){ /* ... */ }

When you call foo with a List or List, the compiler will complain that the types don’t match. (unless you provide overrides of foo). Instead, make foo a generic method, and specify a constraint on the type:

 
public void foo<T>(List<T> myList) 
    where T : Aclass 
{ 
  /* now you can treat
      myList as a List<Aclass>*/ 
}

This link goes over generics in c# in detail:

MSDN on Generics