Saturday, August 14, 2010

getting reacquainted with javascript

Ok, I'm admittedly a little late to the party here. Lots of people are doing really, really cool things with javascript these days.

So, I've been using rhino to whip together my java experiments lately. Setup is trivial, you just need java and js.jar.

  1. download rhino 
  2. extract js.jar (at least)
  3. for an interactive shell, run java -jar js.jar
  4. or run a script using java -jar js.jar some-javascript-file.js

Once you have rhino, all sorts of java-ish things can be whipped up as quick hacks.
A quick http server, for example, goes something like this:

function main() {
  var s = new java.net.ServerSocket(8080)
  while (true) {
    var client = s.accept()
    var sc = new java.util.Scanner(client.getInputStream())
    var method = sc.next()
    var path = '.' + sc.next()
    var out = new java.io.PrintWriter(
            new java.io.OutputStreamWriter(client.getOutputStream()))
    try {
      var f = new java.io.FileInputStream(path)
      out.println("HTTP/1.1 200 Success")
      out.println("Content-Type: text/html")
      out.println()
      for (var c = f.read(); c != -1; c = f.read())
        out.write(c)
    } catch (e if e.javaException
        instanceof java.io.FileNotFoundException) {
      out.println("HTTP/1.1 404 File not found")
      out.println("Content-Type: text/html")
      out.println()
      out.println("<html><body>")
      out.println("<h1>File not found</h1>")
      out.println("</body></html>")
    }
    out.flush()
    out.close()
  }
}

main()

Wait, what about a threaded server you say? Try this on for size.

function main() {
  var s = new java.net.ServerSocket(8080)
  while (true) {
    var client = s.accept()
    var t = java.lang.Thread(function() {
          var sc = new java.util.Scanner(client.getInputStream())
          var method = sc.next()
          var path = '.' + sc.next()
          var out = new java.io.PrintWriter(
                  new java.io.OutputStreamWriter(client.getOutputStream()))
          try {
            var f = new java.io.FileInputStream(path)
            out.println("HTTP/1.1 200 Success")
            out.println("Content-Type: text/html")
            out.println()
            for (var c = f.read(); c != -1; c = f.read())
              out.write(c)
          } catch (e if e.javaException
              instanceof java.io.FileNotFoundException) {
            out.println("HTTP/1.1 404 File not found")
            out.println("Content-Type: text/html")
            out.println()
            out.println("<html><body>")
            out.println("<h1>File not found</h1>")
            out.println("</body></html>")
          }
          out.flush()
          out.close()
        }
      )
    t.start()
  }
}

main()

For more reading about rhino and javascript including how to structure, organize, and manage your code for larger projects, try these great posts.

http://steve-yegge.blogspot.com/2008/06/rhinos-and-tigers.html
http://www.adequatelygood.com/2010/3/JavaScript-Module-Pattern-In-Depth
http://peter.michaux.ca/articles/javascript-widgets-without-this
http://www.jspatterns.com/

Sunday, August 8, 2010

reading files in java

Just came across this aging, but still surprisingly relevant analysis of reading files in java. Basically compares the relative performance of several common (and some newer, lesser known) file reading methods... quite interesting.

emergency lisp

Keep this excellent lisp post handy. It is perhaps a little dated, but only in terms of the actual date of the post. It provides a good introduction to lisp programming, especially when transitioning from another, less functional language. Even though it deals specifically with emacs lisp, the concepts are close enough.  Definitely useful the next time a co-worker needs convincing using clojure.

Wednesday, August 4, 2010

your test suite is broken

Take the quiz and fess up if your test suite is broken. Remember, test suites are software too, and as software, they need maintenance and upkeep just like the rest of the code your write.

Tuesday, August 3, 2010

looking forward to 2.6.35

Based on the changelog and this writeup, the latest linux kernel release appears to be pretty power-packed. I'm particularly looking forward to the performance improvements around spreading network load across cpu cores.

On a slightly related note, I find the whole kernel code shepherding process amazing. How many managers have the ability to rattle off the number of post-release-candidate commits (with averages and comparisons against previous release candidates)? Never mind the whole staging and merging process. I think many software teams could learn quite a bit about managing the development process across distributed teams by letting go of centralized source control and watching the linux kernel developers.

Monday, August 2, 2010

nice perl tip

I just came across this excellent perl tip. I'm not sure I'd use it exactly as written, but the idea of being able to open perl modules by module name instead of file name is certainly appealing. Now, to figure out how to apply this to other languages too.

Sunday, August 1, 2010

autonomous agents for software testing

I've been thinking about software testing quite a bit lately. I've been thinking about the artificial intelligence/algorithms used in game programming too. And so naturally, at some point it occurred to me that the same algorithms used to make all those characters, monsters, cars, or whatever meander in and out of the background scenery of our favorite games might be useful in software testing scenarios.

Imagine you need to test a particularly hard-to-pin down bug - one that only happens during periods of high usage. It seems to me that you have a couple of options. You can force your users to pitch in and help with testing (not likely, and certainly not popular). You can beg your fellow programmers to do their best to mimic users (also not likely or popular). Or lastly (wishful thinking) you could fire up some program which will spawn an army of autonomous agents to meander through common use cases and behave as normal users creating the necessary "background traffic" needed for testing.

This is currently just an idea in its infancy, I don't know of any actual implementations. But it does seem like an interesting area for some research and coding. One could imagine initial versions would need lists of steps that could be invoked at random intervals and sequences by many agents through some programming interface. However, far off future versions might know how to inspect user interfaces for menus, buttons, and dialog boxes - simulating mouse clicks and keyboard entry (valid or invalid) until something happens in response.

Although I haven't found anything this sophisticated yet, it occurs to me that areas of security research might already have made progress on similar tools. Black-box penetration testing usually involves sending random (or perhaps not so random) payloads in an attempt to illicit an unexpected error or otherwise interesting response.

So, any takers want to whip something like this up for me?