Friday, July 06, 2007
Children's show opening
Thursday, July 05, 2007
Fifth of July
Michele Oliver blogged about the song "This is America", on which Ilene and I can be heard as part of the backing chorus near the end of the song. It was recorded in 2001, partly in response to the 9/11 attacks.
Thursday, April 12, 2007
A Guice utility for binding to legacy classes
You're going along, happily Guicing your world, when you run into a snag. There's a class Legacy that you'd like to be able to bind things to, but you can't edit the source to add the @Inject annotations. It looks like this:
public class Legacy implements SomeInterface {
public Legacy(LegacyDependency dep, String str) {
...
}
public void initialize(LegacyConfig cfg) {
...
}
...
}
And you wish it looked like this:
public class Legacy implements SomeInterface {
@Inject public Legacy(LegacyDependency dep,
@MyAnnotation String str) {
...
}
@Inject public void initialize(LegacyConfig cfg) {
...
}
...
}
You're used to Guice by now, so right away you think, "No problem, I'll use a Provider!"
public class LegacyProvider
implements Provider<Legacy> {
public Legacy get() {
Legacy result = new Legacy(dep, str);
result.initialize(cfg);
return result;
}
@Inject LegacyDependency dep;
@Inject @MyAnnotation String str;
@Inject LegacyConfig cfg;
}
...
protected void configure() {
bind(SomeInterface.class)
.toProvider(LegacyProvider.class)
.in(WEB_APPLICATION_SCOPE);
}
So you've written a Provider<Legacy>, and it works. But now you have this extra class to maintain. It's not complicated, in fact it's quite trivial. It seems like something you shouldn't have had to write. You'd rather write something like this:
bind(SomeInterface.class)
.toProvider(
fromConstructor(Legacy.class,
Key.get(LegacyDependency.class),
Key.get(String.class, MyAnnotation.class))
.injecting("initialize",
Key.get(LegacyConfig.class))
)
.in(WEB_APPLICATION_SCOPE);
If this looks like something you want, check out my implementation in the DWR-Guice integration sources. The javadocs are there, too, but they aren't complete. It doesn't have anything to do with DWR, but it seems like a nice convenience to provide.
There are also several flavors of factory-method-based providers, so you don't have to write a special provider just to call a factory method.
I wrote it because even though I've been able to jettison a lot of baggage as I migrate from Spring to Guice, there are still Spring things I want to keep using, like JavaMailSender. I don't want to have to write provider implementations for each one.
Thursday, April 05, 2007
Guice support in DWR
I'd been using DWR with Spring to wire together all the components of the Seat Yourself on-line ticket sales web application for almost a year and I was pretty happy with the combination. Then a few weeks ago, just as I was considering how to make the webapp more easily configurable, to support rapid administration and self-configuration of many customers, Josh Bloch suggested I take a look at Guice, and I suddenly realized just how fragile and unmaintainable was all that XML I had written for DWR and Spring.
Of course I could use Guice without integrating it with DWR, but one of the things that had always bothered me about DWR (and many other tools, not just DWR) was that everything -- remoted objects, data transfer objects, extension classes -- has to be concrete and public, with a public parameterless constructor, and everything works through setter injection, which makes things difficult. I want to work in terms of interfaces, with implementation classes that have final fields for injected state.
Guice looked like a way to have it all: easy remoting with type-safe (pure Java) configuration. I wrote a Guice integration package for DWR, and Joe Walker signed me on as a DWR contributor so I can help maintain it as part of the DWR distribution. The package Javadoc describes how to use it along with a simple example.
I'm still in the early stages of applying it to the Seat Yourself web sales application, but already the power of Guice has made things simpler. Each customer (where a customer is ticket-selling entity, like a theater) is associated with a domain where all their data -- seat charts, performance information, pricing information, patrons and their reservations, and holds on seats -- is maintained. When a user visits the web store to buy tickets, the link contains a domain name, e.g., "t3" for Theatre Three. Before Guice support, I had devised a complicated system using reflection and proxying to route the user request to the appropriate service object. It was so involved that I had trouble explaining it to my partners, both smart people. Not being able to explain something is a bad code smell.
With Guice-injected remoted objects, I can define a new scope, domain scope, where the details of providing the appropriate domain-specific service object are neatly encapsulated and managed by Guice. All I have to do is write something like this in my binding code:
bindRemotedAs("Tix", WebstoreService.class) // interface
.to(WebstoreServiceImpl.class) // impl
.in(DomainScopes.DOMAIN); // scope
where the interface looks like this:
public interface WebstoreService {
PerformanceAvailability getPerformanceAvailability();
...
}
Only the methods of WebstoreService are exposed to the world, even though the implementation class might have other public methods. With the Guice support, I don't need to specify which methods to expose. As usual with DWR, on the JavaScript side I can write things like:
Tix.getPerformanceAvailability({
callback : function(availability) {
notifyPerformanceAvailabilityReceived(availability)
},
exceptionHandler : ...
});
Because Guice has Spring integration, I can migrate my existing Spring-based code smoothly. Because it has JNDI integration, I can rewrite the code that manages the domain-specific configuration to use whatever LDAP back-end I like, instead of having to maintain an assortment of XML files and registry settings. We've already had problems with syntax errors in the XML configuration files, so this will save us a lot of heartache.
Guice also has support for AOP Alliance method interceptors, which means that on most of the occasions when I would feel most tempted to use AspectJ, I can stick to pure Java. Not that I have anything against AspectJ, but it's a different language and one more thing to worry about. I want to save it for the occasions when I really need it (as was the case for another submodule of our project).
Wednesday, January 10, 2007
Blurb in Yale Alumni Magazine
Tim Peierls (JE) (tim@peierls.net) writes that 2006 was exceptionally busy, with his hand in a wide range of diverse ventures: "I helped produce fellow JEer Josh Rosenblum's musical show, Bush is Bad; the title says it all. I co-wrote a book, Java Concurrency in Practice (Addison-Wesley). If the title makes sense to you, then you need the book; if not, then ... not. I co-produced (with Gary William Friedman) an album by jazz vocalist Stevie Holland, More Than Words Can Say. And I developed an online ticket sales application that went into production in November. See www.SeatYourself.biz for details."
Thursday, December 07, 2006
Rescued from Nokia
I had been unable/unwilling to download the many photos I had accumulated on my old Nokia phone. Today, however, I put the Treo head-to-head (well, head-to-side) with the Nokia, and I transferred them all over IR to the Treo, then down to the PC, then up to my public gallery with Picasa.
For example, this was my phone's background for a long time:

The full album:
Monday, December 04, 2006
Grinch opening
[update 2007-Sep-15]
That link might be down for good, so here's what I posted:
The new Broadway production of How the Grinch Stole Christmas opened on November 8, my birthday. My friend Josh Rosenblum is the musical director for the show. As a birthday present he got my family in on opening night, including passes to the opening night party across the street at Madame Tussaud’s wax museum.
The show runs about 75 minutes, with no intermission. It was mostly not my cup of tea, but both of my kids were riveted and said they would like to see it again. In addition to providing music direction, Josh wrote some of the incidental music and did the vocal arrangements; there were several lovely moments of multipart singing, which is what I go for. There was also one very funny line that I’m told was an ad lib during rehearsals; I won’t give it away, but I’ll mention that it happens just before Cindy Lou Who’s big number.
The party at Madame Tussaud’s was huge. I had never been to a wax museum before, so I had what I gather is the usual reaction of mistaking wax figures for real people and vice versa. I would have liked to stay longer, but we discovered that Tessa, our oldest, is afraid of wax figures, so we had to hustle through quickly and miss a lot.
