Friday, August 14, 2009

Live from Second Life

“Live from Second Life!” That's how people who are broadcasting over Internet radio while logged into Second Life tend to announce themselves. Which, given the immersive nature of the medium, feels entirely natural until you think about it. Of course, they're actually broadcasting from wherever they are in Real Life. But since whatever they're saying usually concerns the people whose avatars they see in the vicinity of their own avatars, the feel of addressing an intimate gathering is inescapable.

But this weekend I'm blogging live from Second Life in an entirely different sense. I'm attending the Second Life Community Convention in San Francisco. The first sessions of the convention began yesterday afternoon.

I was afraid the convention might be a little dry—lots of people with Real Life or Second Life businesses nattering on about Synergies and Leveraging Brands and other buzzword-laden nebulosities—but it's been a lot more fun than that. I crashed a couple of Art track sessions yesterday. I know zip about art, but I had a blast: artists can be just as creative in conversation as on the metaphorical canvas. The high point of the afternoon was a few short scenes from plays prepared by Z. Sharon Glantz (Lailu Loon in Second Life), who had us read the scenes and then discuss how we'd stage them in Second Life. These were classic brainstorming sessions where wild ideas flew thick and fast. Lailu's stated focus was on how to make Second Life drama that would be accessible to people who weren't familiar with Second Life, but I'm afraid I kept coming up with ways to incorporate Second Life in-jokes into the scenes (are jokes actually funnier when only your friends get them?).

Making virtual worlds accessible to people who aren't familiar with them is a theme of several conversations I've had so far. I was talking with a Belgian journalist last night (whose name I failed to catch) and he was complaining about the number of job applicants he encounters—people in their 20s—who aren't familiar with new media. He says he asks them in interviews, Do you play World of Warcraft? Do you blog? Journalism isn't quite the manual-typewriter-in-an-exotic-location profession it used to be.

This morning's keynote address was from Ray Kurzweil, appearing to us from Second Life, projected on a screen at the front of the room. His presentation focused on the exponential growth of various technologies, including, in recent years, the use of virtual worlds. His contention that within 20 years or so many people will have neural implants that let them interface directly with virtual worlds seemed a little early to me—I'm not sure that many people will move into brain hacking that quickly—but it's clear to me that enough people find virtual worlds compelling that people will keep looking for lower-friction ways to inhabit them.

Sunday, August 9, 2009

Unconstructable Token

Here's a story about a problem, and about a pattern that solves the problem. Both the problem and the solution are specific to Java, because they involve Java's visibility rules.

I wrote a Java method m as part of a project at work. It was an implementation-detail method, not to be called by the client applications of the project, that needed to be called only in a certain context. I provided a public method p that set up the context and called m—but as happens so often, the project had evolved to have a structure more organic than organized, and p was in a different package from m, which meant that m had to be declared public.

My coworker, writing a client application of my project, wanted to invoke the operation that p performed, but didn't recall the name of the method he wanted to use. So, using his helpful IDE, he searched. Well, I had given m and p similar names—no, I didn't really call them m and p, but gave them names describing what they did—and so my coworker's IDE found m, and he wrote a call to m in his code. Since he didn't call p, the context required for m to work properly was not set up, and m blew up when he called it, and he wasted some time trying to figure out why before he came to me and I told him he should have called p instead.

In my defense, I had clearly stated in the Javadoc for m that it was to be called only from p, not from the client application. Unfortunately, my coworker searched for just an identifier in his IDE, and the IDE didn't know enough to read the caveats I had put in the Javadoc and wave red flags in front of my coworker when he called the wrong method.

(OK, I know what you're thinking. I shouldn't have set up my system so that m and p were in different packages in the first place. This kind of setup—a publicly visible method not meant to be invoked by the public—is one that should have been caught in the design phase, or been solved by something like the export controls in the eternally-not-quite-ready-for-prime-time Java Module System, JSR 277. And in this case, you're probably right, at least in a perfect world. But this problem can also occur where refactoring and modularity don't work, as I show below; so for now, please just accept the problem as legitimate.)

Now for the pattern I adopted to solve the problem. I haven't seen any discussion of a general solution to this problem elsewhere, so I'm going to take the initiative and name the pattern: Unconstructable Token.

In Unconstructable Token, a method m that is declared public but should be invoked only from a particular context takes a parameter of a type T that can be constructed only in that context. m verifies that the T is not null, and gives a sensible error message if it is null—a runtime enforcement of m's restricted visibility that is admittedly inferior to a compiletime enforcement, but the best that can be managed if m must be declared public. (In practice, this is almost as good as compiletime enforcement, because programmers are unlikely to try to pass null as a method argument without explicit permission.)

A schematic example:


package p1;

import p2.C2.T;

public class C1 {

public void m (C2.T token) {
if (token == null)
throw new IllegalStateException(
"Cannot call C1.m directly; call C2.p");
do something useful
}

}


package p2;

import p1.C1;

public class C2 {

public class T {

T () {
// constructor is *not* public, so can only be
// called from package p2
}

}

// The token doesn't have to be a singleton, but is here:
final T t = new T();

public void p (C1 c1) {
set something up
c1.m(t);
finish up
}

}


The example shows a token with no functionality of its own, but it is often convenient for C2 to place some of the data or actions needed to coordinate between m and p in the token itself.

The hoped-for result is that your documentation-ignoring coworkers will quickly realize they can't get a hold of a T, and so can't call m; and therefore they keep searching and stumble on p, which they should call. If they are so bold as to call m(null), they'll get an error message at runtime that points them in the right direction.

Of course this pattern is Java-specific. In C++, you wouldn't declare m public, but instead declare p to be a friend of m, and you'd be done. But the Java folks don't seem inclined to take the language in the direction of friend, so that's unlikely ever to be an option for Java.

Anyway, are you sold yet, or is Unconstructable Token more antipattern than pattern? I think that depends on context. In the distant, shining world of JSR 277, this system could be a single module that publishes C2, but not C1 or T. m would still be declared public, but because it's in a module that doesn't export it, it's not visible to the client application. But in the real world of deadlines and pointy-haired bosses, we can't wait for Java 7 (which will surely include an implementation of the module system—won't it?), and we don't necessarily have the luxury of refactoring the system to put all the relevant mechanism into one package (if that even makes sense), and we probably don't want to get bogged down in something as heavyweight as OSGi (which is an existing module framework specification, but more oriented towards modules that may be added and removed during execution).

I may be displaying undue favoritism because I invented Unconstructable Token, but I think it's not so ugly that you need to be ashamed of using it, especially if you document that you're doing so.

Now, as promised, a situation where Unconstructable Token can be indispensable: the case of synthesized code. If you are writing a class loader that modifies or generates code to implement the rules of some framework, you may want the generated code to call methods in the framework (ordinary methods that you write as part of the framework, not generated methods). However, even though the framework methods may perform actions that don't make sense except when called from the generated code, you must make them public in Java—otherwise, you won't be able to call them from code loaded by your class loader.

If you invoke the generated code in question directly from the framework, you can just pass an Unconstructable Token to the generated code, and the generated code can pass it back when it calls back into the framework.

The solution is more complicated if your framework methods can be called from arbitrary places in the generated code. I haven't dealt with such a situation in practice, but it seems to me you could add some generated code to each class to wind up putting the Unconstructable Token in a private variable in each class containing generated code. Since I'm too lazy to figure out whether this really works, or how to do it tidily, I'm going to decree this an Exercise for the Reader. At least, until such time as I need to do it myself.

Note that neither refactoring nor modularity gets us anywhere in the case of generated code. Assuming your framework doesn't load itself, the generated code you load with your class loader will necessarily be in a different package from any of the framework packages (because they have different class loaders). And how would you write a module so that it exported a method to the generated code, but not handwritten code in the same package? I'm not familiar enough with the module system proposals to say definitively that it's impossible, but it doesn't sound easy.

Saturday, August 8, 2009

The JSR 308 Story

OK, after a little reading, I think I've figured out what JSR 308 does and does not do.

Although there is a bit of speculative language scattered in the JSR 308 materials about runtime enforcement of the rules associated with various annotations, no enforcement mechanism is currently available. That is, JSR 308 (at least in its current incarnation) is all about compiletime, and not about runtime.

Besides the immutability-related annotations of Javari, the JSR 308 kit includes an alternative immutabilty checker, IGJ, and some other annotations for checking:
  • Nullness: @NonNull and @Nullable
  • Interning (whether two objects of which equals is true may be distinct instances): @Interned
  • Locks: @GuardedBy and @Holding
as well as a clunky-looking mechanism for subtyping by annotation, the Basic checker.