astradele

Archive for July, 2005

Dropping JAXB

Posted by GJ on July 30, 2005

For Coconut, the side software project I work on, I used to use the JAXB package from Sun. JAXB can parse schemas and generates classes that handle representing XML documents as a tree of objects.

It sounds good in theory, but I ran into two problems in using it:

  1. Schemas don’t seem to be very good at specifying really wacky rules. It can do it, but it gets very verbose. The main case I ran into was that I had a tree of elements defined, and depending on the value on an attribute near the root of the tree, the validity rules of the rest of the tree changed very slightly. e.g. a XML document representing “John Doe” may or may not have a street address element; however, if his street address is specified, then a sibling element for the postal code is mandatory.
  2. JAXB generates a set of classes. I then go on to use those classes in the rest of the application, by classes containing business logic. However, those classes are sensitive to the schema. The schema is not an international standard - it’s just my current expectations on a custom message format. Thus, it’s subject to churn, which causes the object model to churn, which causes a lot of breakage. This is worsened by the previous point, that seemingly small rule adjustments cause great increases in schema verbosity.

I’m not particularly well-versed in schemas, and I picked up JAXB based on a high level description from a coworker; it’s possible I’m misunderstanding something. However, in hindsight I should have known better, as I’ve worked on another project that used an XML schema (with a standards body) to generate a core object model - that one didn’t turn out well either.

Posted in techie | No Comments »

Outsmarted again

Posted by GJ on July 24, 2005

I hate being outsmarted by my cat. She figured out how to use my new laser printer to reach the shelf that hitherto was out of reach (and consequently had unapproved kitty toys, like unused AA batteries). Funny that she’s so smart at getting past all the obstacles I put on her behaviour, yet she’ll ignore me when I ask her to do a simple trick for food. Or maybe that’s an indication of how smart she is, too. :)

Posted in everyday | No Comments »

iTunes for Windows skipping

Posted by GJ on July 23, 2005

My audio player of choice is usually foobar2000, but I do like iTunes as well. It integrates a lot of different features, particularly a radio directory, and podcast facilities, that I find quite useful. It’s also pretty. :)

However, I found that iTunes skips (playing a podcast or radio stream) when I did something else on the computer that incurred non-trivial hard disk activity. A quick search on Google found me the blog entry How to make iTunes for Windows stop skipping, but I don’t think it’s a satisfactory solution. Setting the output device to waveOut causes mixing problems (an artificial example is playing iTunes and watching a DVD) - IIRC it prevents mixing entirely, although fact searching that seems to say it’s merely prone to problems.

At any rate, I seem to have fixed my problem by following the same approximate steps (Control Panel, QuickTime, Sound Out), but using Options to increase the buffer size from the default 120ms to 1200ms, instead of changing the output device away from DirectSound. Makes sense in a way, although I’m not sure why a radio stream would be affected by hard disk activity.

Posted in techie | No Comments »

North 44

Posted by GJ on July 23, 2005

Trying to make a 5:30p reservation on a hot summery day in office dress clothes, when the restaurant of choice is a several blocks walk outside, is not recommended.

However, the aforementioned restaurant, North 44, is absolutely recommended (as long as you don’t worry about the heft of your wallet).

Arriving just in the nick of the time, and feeling decidedly sweaty and unglamorous for such a high end restaurant, the first thing I noticed going in was the A/C. The next thing was that North 44 is a two story affair, with tables on the ground floor, and stairs to an additional level above. Most of the restaurants in the Yonge-Eglinton area just have one floor.

The restaurant was still quite empty, and after being seated, the table’s waiter came by and asked about drinks. Overall, the waiter was fine, but I think he was trying a little too hard - his speech came off as more than a little artificial, with a certain amount of excessive floweriness.

After some deliberation over the Summerlicious menu, me and my dinner partner finally decided. We both upgraded certain aspects of our respective courses - after all, how often does one come to such a restaurant? The courses were: foie gras, salmon, and a dessert (whose name I forget); the other (mine) was risotto, lobster & steak, and a “trio of desserts”.

As I recall, the service wasn’t particularly slow or swift. The appetizers were an interesting presentation, and signalled the look of the rest of the course.

I really like the name “risotto” on paper, but I always forget what it actually is. Rice that’s been soaked in a tomato-type broth is what I think this one was. Interestingly, the rice was *just* on the uncooked side of done; I didn’t mind at all.
127_2781

Foie gras - goose liver. I’m normally not a fan of liver at all, but I must admit, this did look very nice. I tried a little bit. It reminds me of eating some steak fat, though of course much more tender and flavourful, with that “liver” taste. My dinner partner felt this angle was more “artful”. Looking at it now, I think I agree.
127_2783

The “surf ‘n turf” was much smaller than I had expected. However, i *greatly* enjoyed the lobster. Perhaps it’s because it’s been awhile, but that was the best piece of lobster that I recall. Buttery (but not dripping in any way), sweet like sweet corn is sweet… yum. The steak was good, too, but it’s the lobster piece that I remember.
127_2787

The salmon was quite interesting. The presentation was very good, as you can see in the picture; there’s also a scoop of mashed potato behind the salmon. If you look closely, however, you can see the salmon is seared outside, but still red on the inside. It tasted quite good. it wasn’t exactly like having sashimi, nor like having fully cooked salmon, although leaning more to the former than the latter.
127_2788

I’m usually a glutton at meals, particularly when it comes to either novelty or desserts. So for the prospect of novel desserts, I upgraded more to have a sampler.

The dessert on the right was a light, cream (I think) and berry mixture. Those black spots on the right were edible seeds of some sort. Very sweet.

The centre is creme brulee. The caramelized layer was extraordinarily thin; I think I’d have liked a slightly thicker one to add a sweeter taste to the experience. The filling was creamy, but not very sweet. Probably the most “understated” creme brulee I’ve had.

The dessert on the left was banana based. IIRC, the shell was deep fried banana, and the inside under the cream was also a banana slice. More of a demonstration of skill and appearance rather than taste perhaps (though it tasted well).
127_2790

The dessert of the other course was a larger version of the cream and berry mixture (I wish I remembered what it was called).
127_2794

So that was North 44, some very fine dining. Due to the various upgrades, the bill was more than I expected: ~C$60 for me after tips and taxes I believe. Still, it’s a rare occasion to go, and it was a fun cuilinary tour. I look forward to when I can do it again at North 44’s sister restaurant, Bymark.

Posted in everyday | Tagged: | No Comments »

Red Violin Brazilian Steakhouse

Posted by GJ on July 15, 2005

Red Violin Brazilian Steakhouse

Absolutely delicious. Expensive (C$30), but it’s buffet style. The entrance also doesn’t look like much (washed out sign, small presence from the street, up some stairs of functional decor). I’ve never had Brazilian, but regardless of authenticity, this was certainly different and delightful.

The appetizer island from the south:

The appetizer island from the north:

Unfortunately, there are no pictures of the huge platter of cooked, shelled shrimp on the west side, nor of the steamed mussels in white wine sauce on the east side. The aroma of the shrimp, however, will ensure you never miss it in person.

Some fried appetizers delivered to the table; those are fried bananas in the upper right:

Non fried appetizers at the table; you mix the three together (bread-crumb type mixture, rice, bean mixture) into a delectable snack:

The entrees are brought from the kitchen on large metal skewers. It’s a buffet, so the entrees (meats for the most part- chicken, beef, pork, etc.) just keep coming out as they become ready. The waiters ask if the diner would like any of the current offering, and if accepted, the waiter loosens a piece with his knife and the diner use the tongs that each diner has to remove it from the skewer:

Sadly, there is no picture of arguably the best food there - roasted pineapple with cinnamon. Everyone at the table helped themselves to many portions of that each time the pineapple was available. Very sweet, none of the typical pineapple “bite”, juicy. I’d go back just for the pineapple.

I don’t know if this was an authentic Brazilian experience, but this is a place to go in any case. Absolutely worth the price, and much better fare than regular buffets. Remember to come hungry, and have the pineapple no matter what.

Posted in everyday | Tagged: | No Comments »

What I read

Posted by GJ on July 7, 2005

In keeping with the theme of this blog (i.e. if you were wondering about what I do with my time), I posted some appropriate links in the sidebar. They show some of the material I read online (”feeds”), comics that I follow, sites I bookmark, and my queue of books I intend to eventually read. A lot of the content is computer related though: it’s easy to separate blog content into tech and non-tech, but it’d be a hassle to separate the content in thoses links.

FYI, I’m a fan of getting all my data in one place, and just the data (e.g. no ads). So my setup automaticaly downloads all those blog entries onto my server for reading in a single web page, copies all the comics into a lone webpage, and use the del.icio.us service to centrally manage all my bookmarks across different computers and browsers.

BTW, if my bookmarks seem excessively computer-related, it’s because I also bookmark sites as part of the research I do for my day job. Try using the category “tags” to filter.

Posted in everyday | No Comments »

Executable startup JAR

Posted by GJ on July 2, 2005

In order to mask the complexity of starting the Java application, I decided that Jetty had the right approach: creating an executable JAR that was used in lieu of a regular startup script (or batch file). It was pretty easy overall, though I had to peek at Jetty’s source to be reminded of the existence of URLClassLoader.

The idea is to create a simple starter class in an executable JAR, which instantiates a custom ClassLoader used to load the real classes for the program. It also does any other tedious setup work, like setting properties or starting the logging system (via reflection, b/c the custom classloader will have the classes, rather than the starter’s ClassLoader).

This lets me do any custom dynamic configuration I want. I load all the JAR libraries from the “lib” subdirectory, and use those classes as the CLASSPATH to run the real program. Since any JAR file is loaded, upgrading is as simple as deleting a JAR and dropping in a new one; the name of the new JAR and old JAR doesn’t matter. Having name not matter is useful to me, as the JAR files I build are versioned and timestamped in their name for easy recognition.

Admittedly, I could do all this using a script, and dynamically building the command line used to invoke the Java runtime. However, I’d have to write at least two scripts (Windows and UNIX), and I’d have to either write for the lowest common denominator toolset I can assume is present on the system (e.g. grep, sed, VBScript, Windows CMD scripts) , or bundle my own (e.g. Perl). With a Java starter, I’m guaranteed access to the Java runtime, which is a very functional “lowest common denominator”. Besides, why bother working with a script language to specify Java-centric ideas, when you can use Java to specify Java-centric notions?

In case you’re curious what I did:

import java.io.File; import java.net.MalformedURLException; import java.net.URL; import java.net.URLClassLoader; import java.util.ArrayList; public final class Start { public static void main(String[] args) { try { // Search for the Start class that’s in a JAR from the library, rather // than the Start class that we’re currently using. getlibraryClassLoader().loadClass(Start.class.getName()).getMethod( “start”, new Class[] { String[].class }).invoke(null, new Object[] { args }); } catch (Exception e) { e.printStackTrace(); } } public static void start(String[] args) { try { ClassLoader loader = Start.class.getClassLoader(); // Jetty uses the ClassLoader assigned to the thread to load classes for // the servlets. Thread.currentThread().setContextClassLoader(loader); Class serverClass = loader.loadClass(”org.mortbay.jetty.Server”); Class listenerClass = loader.loadClass(”org.mortbay.http.SocketListener”); Object server = serverClass.newInstance(); Object listener = listenerClass.newInstance(); listenerClass.getMethod(”setPort”, new Class[] { int.class }).invoke( listener, new Object[] { PORT }); serverClass.getMethod(”addWebApplication”, new Class[] { String.class, String.class }).invoke(server, new Object[] { WEBAPP_CTX, WEBAPP_DIR }); // addListener() and start() aren’t defined on org.mortbay.jetty.Server, // but defined on its base classes. loader.loadClass(”org.mortbay.http.HttpServer”).getMethod(”addListener”, new Class[] { loader.loadClass(”org.mortbay.http.HttpListener”) }) .invoke(server, new Object[] { listener }); loader.loadClass(”org.mortbay.util.Container”).getMethod(”start”, new Class[0]).invoke(server, new Object[0]); } catch (Exception e) { e.printStackTrace(); } } public static ClassLoader getResourceClassLoader() { if (g_resourceClassLoader == null) { try { g_resourceClassLoader = new URLClassLoader( new URL[] { RESOURCE_DIRECTORY.toURL() }, null); } catch (MalformedURLException e) { throw new RuntimeException(”Couldn’t create resource ClassLoader.”, e); } } return g_resourceClassLoader; } public static ClassLoader getlibraryClassLoader() { if (g_libraryClassLoader == null) { try { ArrayList urlList = new ArrayList(); // Search the JAR directory for anything that looks like a JAR and add // it to the ClassLoader’s search path. for (String childFilename : LIBRARY_DIRECTORY.list()) { File child = new File(LIBRARY_DIRECTORY, childFilename); if (child.isFile() && childFilename.matches(”.*\\.jar$”)) { urlList.add(child.toURL()); } } // The configuration ClassLoader is the parent fo the URLClassLoader, // mostly because Log4J automatically searches for “log4j.properties” on // its first use. g_libraryClassLoader = new URLClassLoader(urlList .toArray(new URL[urlList.size()]), getConfigurationClassLoader()); } catch (MalformedURLException e) { throw new RuntimeException(”Couldn’t create library ClassLoader.”, e); } } return g_libraryClassLoader; } public static ClassLoader getConfigurationClassLoader() { if (g_configurationClassLoader == null) { try { g_configurationClassLoader = new URLClassLoader( new URL[] { CONFIGURATION_DIRECTORY.toURL() }, null); } catch (MalformedURLException e) { throw new RuntimeException(”Couldn’t create confiuration ClassLoader.”, e); } } return g_configurationClassLoader; } private Start() {} private static URLClassLoader g_libraryClassLoader; private static URLClassLoader g_resourceClassLoader; private static URLClassLoader g_configurationClassLoader; private final static int PORT = 8080; private static final String WEBAPP_DIR = “web/”; private final static String WEBAPP_CTX = “/”; private final static File CONFIGURATION_DIRECTORY = new File(”config”); private final static File LIBRARY_DIRECTORY = new File(”lib”); private final static File RESOURCE_DIRECTORY = new File(”resource”); }

Posted in techie | No Comments »