Largely Mouseless Browsing

Paul Brown @ 2006-06-14T06:39:00Z

The mouse has its place, but I've never been that fond of the degree to which use of the mouse is required in many GUIs. (I'll take the position that anything that can reasonably be done without the mouse should be.) QuickSilver was a giant leap forward in de-emphasizing the mouse, and Mail ActOn helped; but the browser was largely the domain of the mouse. Now the Conkeror extension for Firefox takes a step toward mouse-free browsing with an interface that seldom requires taking hands away from the keyboard. In addition to Emacs-ish key bindings (including for text areas) and conveniences (like c to copy the current URL to the clipboard), Conkeror numbers the links and form elements on a page for random access (as opposed to the sequential access provided by TAB'ing in a traditional browser interface), and so far it's an improvement. (This approach does run afoul of really fancy interfaces like GMail, but the mouse remains usable for those situations.)

Conkeror also has a nice feature called “webjumps” (derived from an Emacs feature of the same name) that reminds me a bit of YubNub. For example, to find out how far below hair care brands, the NPR Paul Brown, and famous football coaches I rank on Google, I type g followed by google Paul Brown. Or, to add the current URL to my del.icio.us bookmarks, I type g followed by adelicious .. This requires adding the line delicious_username=“prb” (in my case) to your ~/.conkerorrc file and ensuring that Conkeror knows the location of your rc file by telling it on the help page (M-x help-page). (The . in the del.icio.us webjump is just window dressing and could just as well be foo or whatever; the webjump doesn't take any arguments, but Conkeror doesn't interpret a URL as a webjump unless an argument is supplied...)

Bill Clementson has some additional tips here and here.

(comment bubbles) 0 comments

Forehead Slapping with Fit and FitNesse

Paul Brown @ 2006-06-10T18:25:00Z

Fit is an acceptance testing framework that drives test plans off of tables in HTML documents, and FitNesse is a wiki for creating the test plans and viewing the reports. Individual tests are composed of tables, and each table corresponds to a test fixture implemented as a Java class.

As part of its nature as a wiki, FitNesse thinks of camel case “words” as potential pages, and this sometimes clashes with, e.g., the naming of test fixtures or arguments in a test table. FitNesse does this by appending a hyperlinked “?” to the end of the candidate page name, and when the HTML is exported to Fit for evaluation, the “?” goes with it. In other words, FooBar in the wiki text is exported as FooBar? to Fit. (The HTML tag for the hyperlink is stripped.) The way to get FitNesse to not look at a word as a potential wiki page is to escape it, e.g., !-FooBar-!. (And since there is no page that describes the markup that FitNesse uses, I figured this out by reading the source code. It could also be inferred from the wiki markup source of an example, but that's only marginally easier.)

I ran into this with a long, fully-qualified class name in a table that was passed to a custom fixture, but when the fixture tried to load the corresponding class, it wasn't able to find the class. I looked at the exception trace, I looked at the wiki page source, and I looked at my fixture source. Everything looked reasonable. The FitNesse folks suggest debugging by putting in some System.err.println(...) statements, but I went ahead and set FitNesse to configure the Fit runner for remote debugging. This is done by changing the COMMAND_PATTERN variable:

!define COMMAND_PATTERN {java -agentlib:jdwp=... -xp %p %m}

where the ... are the options that make sense for your config. (This is for JSE 5.) I stepped through the fixture and inspected the classloader instance (a URLClassLoader) that I was using, and it appeared to be configured with an appropriate URL to find the class in question. (This was particularly puzzling because the classloader was the one used to load a class in the same package as the class that I wanted to load, and as far as I can tell, the Fit runner does absolutely nothing fancy with class loading.)

As you might imagine from above, the answer is that FitNesse exports the HTML, not the wiki source, and so the “?” after the class name was flowing along as part of the input to the method, and it somehow escaped my notice. The solution was to properly validate input by using a regular expression and provide an informative error message if it failed, which I should have done in the first place, but I had to slap my forehead for taking so long to find that extra “?” lurking around.

(comment bubbles) 4 comments

SOA 2.0: Mud in the Mud Puddle

Paul Brown @ 2006-05-24T20:05:00Z

As I'm getting caught up on some blogs and industry news, I see that the new version of SOA is out, courtesy of Gartner analyst Yefim Natis:

[...] With SOA 2.0, an event-driven architecture is deployed in which software modules are related to business components, and alerts and event notifications are featured. The initial SOA concept has not been event-driven but instead has featured direct calls from one piece of software to another in a client-server process, Natis said. SOA implementations have focused on Web services and subordinates to clients, he said. [...]

As a dyed-in-the-wool pragmatist and skeptic, I've been kind of grumpy about buzzwords and analyst predictions for a while. (I wish that I'd titled that post "Overhype killed the WS-*", but I'm only that clever retroactively.) SOA is a style of decomposing a software system, not a vendor or an analyst property. (Note the lack of a conspicuous "™"...)

A quick search shows that Yefim has had similar views since the Paleolithic (stone tools, yuk yuk...) era of SOA as a buzzword in 2003:

A large part of the integration problem requires implementation of long-running offline business processes. Here, event-driven architecture (EDA), not SOA, is the industry best practice. Unlike SOA, EDA is the design vision for long-running asynchronous processes (SOA is best applied to real-time request/reply exchanges). In EDA, a process node posts an event (in SOA, a process node makes a targeted processing request). In EDA, posting an event reflects results of some past processing (in SOA, making a processing request directs future processing). In EDA, the poster of the event is disconnected from the processors of the event, if any (in SOA, the requestor of service knows the service and depends on its existence and availability).

If nothing else, this sounds like it confuses SOA with RPC and EDA with publish-subscribe. Yefim's on the right track that orchestration (effectively, BPM, once you add the trimmings) is a programming model for building applications in an SOA, but I disagree that SOA or even web services as a specialization of SOA is narrowly scoped to client-server interactions. My minimalist definition of SOA would be:

A service is an autonomous, opaque software unit that consumes and/or produces well-defined messages.
A service-oriented architecture for a software system is a decomposition into services.

Interaction patterns, delivery mechanisms, programming idioms, and data protocols are often aspects of an application of SOA but are neither controlling (in the sense of terminology in a contract) nor defining. That isn't to say that it isn't worthwhile to think about those aspects and approaches. For a detailed, broadly-scoped, pattern-driven perspective on SOA, compare the definition (and dozens of accompanying patterns) from Dragos Manolescu and Boris Lublinsky. (Among other things, they reference the repository of definitions of software architecture from the Software Engineering Institute at Carnegie Mellon.)

(comment bubbles) 1 comment

A Commandline Nano Interface for the Slimserver

Paul Brown @ 2006-05-21T23:34:00Z

We've become almost exclusively digital music consumers. It's easily been six months since we bought our last CD, and a Squeezebox has replaced a CD player as the primary means of playing music in some parts of the house. After some experimentation with SoftSqueeze as a client for the Slimserver that streams music to the Squezebox, I settled on a combination of the headless squeezeslave player with some shell scripts that use the web interface to the Slimserver (via curl) to play, pause, skip, and shuffle, e.g.:

#!/bin/sh
curl -s http://slim.internal:9000/status_header.html\
\?p0=pause\&player=172.16.1.201 > /dev/null

So far, so good with leaving iTunes behind. Now I just need to write a Quicksilver integration...

(comment bubbles) 0 comments

No Need for First-Class Continuations in Java

Paul Brown @ 2006-05-21T23:03:00Z

Gilad Bracha posted a longish entry about continuations:

[...] I’ve thought about this a bit, and here’s my take on why we really shouldn’t add continuations to the JVM. It’s bound to stir up controversy and annoy people, which is a good reason to post it. By far [t]he most compelling use case for continuations are continuation-based web servers. [...]

At least from my point of view, I don't miss continuations in Java, and considering that I program competently in languages that do offer continuations, I will claim that it's not out of ignorance. (I do frequently miss Java not being a functional language.) Every time I've had a real use for continuations, it was worth implementing something specific that wouldn't have been served by a language feature, but then I've only occasionally felt an urge to compact my code down into the smallest and least comprehensible form. (For what it's worth, I think I've used Java's weak goto, i.e., labeled statements, exactly once in seven years of writing Java code...) I've had a customer ask for something to use XML or J2EE or web services, but I've never had a customer ask if I could make sure that continuations get used on the covers. (At least for my money, the coolest thing about Seaside being implemented in Smalltalk is the debugging functionality.)

Continuations are a valid architectural approach to building a participant in one or more stateful conversations, but I don't necessarily see that aligning to a language-level feature. A web server is one example, where the next request is handled by a continuation of whatever handled the previous request, but you'd have to argue with me that snapshotting the stack is the best way to snapshot a session. Process and workflow engines are another example of a system amenable to implementation with continuation-style programming, where a continuation handles the next message or event (e.g., a timeout) to an instance. In the engine case, the execution state is the state of the engine and not necessarily the state of the underlying programming language runtime (e.g., the call stack) and has properties (e.g., durability) not normally provided by the execution state of a traditional programming language.

Many situations in Java where an anonymously created Runnable is passed (e.g., in Swing GUI programming with invokeLater) to be run sight-unseen are essentially instances of a continuation. (Yes, this is more of a closure, since it's local variables that are getting snapshotted and not really the stack...) Other instances where a continuation might be used, e.g., in implementing a generator for a sequence, are a little awkward in Java because it isn't a functional language, but still possible by wrapping up an Iterator the right way. Also, jumping out of nested loops can be accomplished with labeled statements.

Also, from a purely pragmatic perspective, if a given feature of a system really demands an approach that uses continuations at the language level, do I need Java? For one thing, I can get all sorts of fancy language features from other JVM languages like Scala (which is functional), Groovy (which has closures), Jython (which has generators), and JRuby (which is slated to have continuations in v0.9). For another, I could just implement a simple service (SOAP, POX, REST, XML-RPC, etc.) to encapsulate the required functionality or (gasp) write in a language that compiles to native code and get at it using JNI.

(btw, here's a thread at LtU on the topic of Gilad's post.)

(comment bubbles) 3 comments

Most Impressive...

Paul Brown @ 2006-05-21T04:37:00Z

Via BoingBoing, a story about a townhouse in Utah where the occupant accumulated ~70,000 empty cans of Coors Light. (As mentioned in the story, that's a case of beer every day for eight years, although I find it more impressive to think someone drinking a roughly 20 foot by 10 foot, three-foot-deep pool full of beer...)

This reminds me of some silliness from my senior year at Reed College where my roommate Nathaniel Thurston and I managed to accumulate 2,248 empty Coke cans over a year's time. While we were proud of ourselves at the time, it pales in comparison to the guy stockpiling Silver Bullets. We also made a large “funnelator” that used two chimneys on the roof of Old Dorm Block as uprights, and I hope that one doesn't get one-upped anytime soon.

On that subject, the dynamics of the überfunnelator were interesting. The balloons often left the “muzzle” elongated, and some spun end-over-end stretched out into a dumbbell shape. I'd be happy to entertain explanations, although my thinking was that the surface of the balloon was sticking to the funnel as the water was thrown forward, resulting in the stretched out shape.

(comment bubbles) 2 comments

Note to Readers on Categories and Tags

Paul Brown @ 2006-05-21T04:28:43Z

I've pruned the number of categories down to four — business, personal, software, and technology. My interpretation of things like categories is that if you can avoid content (e.g., the Personal category) that you don't have an interest in.

Typo allows the categories to be subscribed to individually, and I have FeedBurner feeds for each of them. The feeds here will shortly be 302'd to the FeedBurner versions (to keep traffic off of this server), but here's the URL format:

http://mult.ifario.us/xml/atom/category/[CATEGORY]/feed.xml

I'm also now tagging all of my posts within Typo, and individual tags can be subscribed to as well. For example, you could subscribe only to posts about BPEL or about Erlang or about entrepreneurship. I won't be creating FeedBurner equivalents for the tag feeds; here's the URL format:

http://mult.ifario.us/xml/atom/tag/[TAG]/feed.xml

There is presently no way to subscribe to multiple tags or multiple categories or a combination of both, but you could always build a frankenfeed with something like Suprglu.

(comment bubbles) 0 comments

All Posts contains 399 items in 57 pages of 7 items each:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57