Tuesday, May 31, 2005

Computers, Robotics and Foosball

What a fantastic combination. I'm surprised I didn't try to come up with that one myself ;-) Apparently I'm too late, the University of Freiburg's (German city of about 200,000) Computer Science Department has developed KiRo, the table soccer robot:
KiRo is a completely autonomous table soccer playing robot: using a camera it perceives the playing field and, dependend upon the current game situation, it decides how the rods under its control should be moved.
Even better is that they commercialized it under the name StarKick. Now if you have a broadband connection go check out some video of what it's like to go up against a robotic foosball opponent. ;-)

Thursday, May 26, 2005

Quicktime 7, H.264 and HDTV

Although H.264 was originally going to be one of those gotta-have-it features offered in the latest version of Mac OS X Tiger, Apple decided to give it away with Quicktime 7. Currently it's only available for Macs and not Windows ("Quicktime 7 for Windows Coming Soon") so you need a Mac to see it but it's worth checking out.

I still have an antenna in my attic for viewing over-the-air broadcasts (a.k.a., peasant-vision) so I'll be the first to admit that I'm a bit quality-picture challenged. But expectations aside, when I downloaded a couple of samples from Apple's HD Gallery I was very very impressed! The 1080p version of the Batman Begins trailer is just huge! My crappy VGA monitor can't even display that resolution (1920 x 816)!

So what's next from Apple? Well it's difficult (if not impossible) to predict. Apple was late to the whole MP3 thing when they introduced iTunes. They weren't the first with a portable hard drive based MP3 player, the iPod, and they weren't the first with an online music store either but look where they are now. They dominate. Microsoft has a Windows XP Media Center and both they and Sony with their next generation game boxes are vying for a spot in the living room. But Apple has the technology, the ingenuity and the ability to make products that resonate with consumers so I'd expect to see something from them that not only embraces the Mac and iLife (as digital hub) but goes beyond to make digital video simple and approachable to the masses.

[Update: I found this blog where the author goes into quite abit more depth. He sounds way more upbeat than me!]

Tweaking log4j

Despite the inclusion of logging APIs into the JDK since 1.4, I still continue to use log4j for my logging needs. Generally I'll also use the commons logging API on top of log4j so that if I should ever change my mind and want to use the "built-in" logging facilities it will be easy.

My recent foray into production deployment highlighted one of the problems with my standard configuation. I have the typical log4j.properties file in the root of my source directory, and log4j is quite happy to find it there. The problem is that it eventually gets buried inside a JAR (Java ARchive) which is inside a WAR (Web Archive) when I build my application and therefore it's not very easy to change the logging parameters once my application is deployed. Specifically, the location of the generated log files is now essentially hard coded, which sucks for deployment.

Fortunately there's a way out of this. If you specify the location of a log4j.properties file in a Java system property called log4j.configuration, log4j will use that file instead of the one buried in your classpath. The only trick is to specify the location as a URL:

java -Dlog4j.configuration=file:/e:/log4j.properties ...

If you're using a Windows Service for starting an instance of Tomcat you can add a system property to the registry value found in HKEY_LOCAL_MACHINE/SOFTWARE/Apache Software Foundation/Procrun 2.0/Node1/Paramaeters/Java/Options where Node1 in my example is the name of your instance of Tomcat.

Secondly, if you're want to define the location relative to a Tomcat installation you can use a dynamic location like this within your log4j.properties file:

log4j.rootLogger=error, R

log4j.appender.R=org.apache.log4j.RollingFileAppender
log4j.appender.R.File=${catalina.base}/logs/MyApp.log
log4j.appender.R.MaxFileSize=200KB
log4j.appender.R.MaxBackupIndex=2
log4j.appender.R.layout=org.apache.log4j.PatternLayout
log4j.appender.R.layout.ConversionPattern=[%d{ISO8601}] %5p (%F:%L) - %m%n

Notice the ${catalina.base} expression. The nice thing about this in a clustered environment like I described yesterday is that you can use the same log4j.properties file for all the instances of Tomcat and can change the configuration for all of them all at once.

Wednesday, May 25, 2005

Tomcat and IIS

I've been busy lately deploying my latest Java web application to production. It's been a bit of an adventure since I don't usually get to play the deployer role. Fortunately I already had my Ant script building the WAR (Web ARchive) file so I was only working on deploying to Tomcat 5.5.9. The twist is that I was deploying to four instances of Tomcat on two physical Windows 2003 servers fronted by the latest version of IIS.

The only reason IIS is involved at all is so that I could use the JK 1.2 Tomcat Connector to do the load balancing. This connector works as an ISAPI Filter and intercepts requests to my appliction (based on the URI) and forwards them on to an instance of Tomcat running my application. The connector does a weighted round robin load balancing and ensures that a request that is tied to a particular session on a particular Tomcat instance (from a previous request) is directed back to that same Tomcat instance.

But perhaps I'm a bit ahead of myself. Let's back up to the Tomcat installations. The first thing I wanted to accomplish was the sharing of the Tomcat JAR files among the various instances of Tomcat. By doing that, I know all Tomcat instances are running the same version and upgradable in one shot. The steps were:
  1. Unzip jakarta-tomcat-5.5.9.zip
  2. Rename jakarta-tomcat-5.5.9 to tomcat for simpler upgrading in the future (if only Windows had symbolic links)
  3. Create a directory called tomcat-cluster-node1 that looks something like this (the files in the subdirectories were copied from the standard Tomcat installation):


/tomcat (renamed from jakarta-tomcat-5.5.9)
/tomcat-cluster-node1 (The subirectories' files are copied from the tomcat
installation.)
/bin (contains service.bat)
/conf (contains catalina.policy, catalina.properties, context.xml,
server.xml, tomcat-users.xml, web.xml)
/Catalina
/localhost (contains manager.xml, host-manager.xml, myapp.xml)
/logs (empty)
/temp (empty)
/webapps (empty)
/work (empty)

Because this installation is on a Windows server I decided to follow the adage "When in Rome, do as the Romans do" and make my Tomcat instances run as Windows Services. Fortunately Tomcat is ready to go with a Tomcat5.exe and a batch script to create the registry entries call Service.bat. The only changes I had to make to the batch file were a few lines at the top to set some environment variables:

set CATALINA_BASE=E:\tomcat-cluster-node1
set CATALINA_HOME=E:\tomcat
set JAVA_HOME=E:\jdk1.5.0_03

then I ran "Service.bat install Node1" and I now have a service that I can easily start and stop. You may want to change the service to "Automatic" to ensure that it gets restarted in the event of a server restart.

Now back to the Tomcat connector installation. I like keeping the redirector stuff separate from the tomcat installation so I created a directory called /tomcat-iis-connector that contains the following files:

isapi_redirect.dll (downloaded from the jakarta site)
isapi_redirect.reg (see below)
uriworkermap.properties (start with a copy from the tomcat/conf directory)
workers.properties (ditto)

The reg file contains some registry entries that the DLL uses at runtime to find your configuration information. Mine looks like this:

Windows Registry Editor Version 5.00

[HKEY_LOCAL_MACHINE\SOFTWARE\Apache Software Foundation\Jakarta Isapi Redirector\1.0]
"extension_uri"="/jakarta/isapi_redirect.dll"
"log_file"="e:\\tomcat-cluster-node1\\logs\\isapi.log"
"log_level"="error"
"worker_file"="e:\\tomcat-iis-connector\\workers.properties"
"worker_mount_file"="e:\\tomcat-iis-connector\\uriworkermap.properties"

Now you have to actually tell IIS about the redirector DLL (notice the /jakarta/ prefix in the extension_uri entry in the reg file. This becomes important in a moment)
  1. Open IIS Manager and create a new Web Site.
  2. Create a virtual directory called "jakarta". This name must be the same as the prefix from the extension_uri value in the registry, and it must be executable.
  3. Go to the "ISAPI Filters" tab of your website's properties dialog and add a filter that points to the isapi_redirect.dll
  4. In the "Web Sites" properties dialog's Service tab select the "Run WWW service in IIS5.0 isolation mode" checkbox.
  5. Disable session state for your website (Properties dialog->Home Directory tab-> Configuration...->Options tab). Just let Tomcat handle your session timeouts.

Now all you have to do is configure your workers.properties file. Mine looks like this:

workers.tomcat_home=E:\tomcat
workers.java_home=E:\jdk1.5.0_03

ps=
worker.node1.port=8009
worker.node1.host=localhost
worker.node1.type=ajp13
worker.node1.cachesize=10
worker.node1.cache_timeout=600
worker.node1.socket_keepalive=1
worker.node1.recycle_timeout=300

worker.loadbalancer.type=lb
worker.loadbalancer.balanced_workers=node1
worker.loadbalancer.sticky_session=1

worker.list=loadbalancer

And then in the cluster-tomcat-node1/conf/server.xml make sure you identify the server with the same name you used when defining the worker in workers.properties, in this case "node1". Without this the "sticky sessions" won't work.

<engine name="Catalina" defaulthost="localhost" jvmroute="node1">

At this point I've only described the installation of a single Tomcat instance, but in reality I have four tomcat instances. So you can imagine more tomcat-cluster-node directories and a few more entries in workers.properties and the addition of those worker names to worker.loadbalancer.balanced_workers:

worker.loadbalancer.balanced_workers=node1, node2, node3, node4

Next you must define the URIs that should get redirected from IIS to Tomcat in the uriworkermap.properties file. Mine looks like this (of course you'll need to change the value of "mycontext" to the context of your app:

/mycontext/*.jsp=loadbalancer
/mycontext/*.do=loadbalancer
/mycontext/*.exe=loadbalancer
/mycontext/*.jpg=loadbalancer
/mycontext/*.gif=loadbalancer
/mycontext/*.png=loadbalancer
/mycontext/*.css=loadbalancer
/mycontext/*.js=loadbalancer
/mycontext/*.jpeg=loadbalancer
/mycontext/*=loadbalancer

Normally, I would like IIS to serve all my static content but I use struts tags to specify the location of images and the JSTL c:url tag to dynamically generate URLs. These tags rewrite the URL and not only include the name of the context (which is configurable at deployment time) but also include the jsessionid in the URL when not using cookies. Unfortunately IIS can't figure out what to do with the jsessionid so your pages come back without CSS or images. Not only do they look pretty awful but if you use js files some functionality may not even work. So I just map everything to Tomcat. On the plus side, deployment is simpler with the single WAR file.

Finally restart IIS and hope everything works! :-)

Monday, May 09, 2005

Updating my Resumé

I recently decided to update my resumé and decided that instead of using a proprietary document format that I would use HTML. If you think about it, a resumé is a great document for HTML. There's no need for an index, foot notes or a table of contents and the elements that remain aren't very complicated either. You have a couple levels of headers, some bulleted lists, and maybe a paragraph or two.

My initial step was to take my RTF document and dump it in a WYSIWYG editor. I used Nvu. I kept everything plain vanilla (no fancy fonts, font styles or colours) and basically edited away. When I was done, I had a factually correct document. The HTML was pristine and wasn't mucked up with a bunch of tags describing appearance. But on the other hand it was an incredibly boring looking resumé. No one was going to give me any extra marks for style.

So I decided I'd spice things up with some CSS. I ditched the WYSIWYG editor and broke out my favourite code editor, jEdit. The first step was to make everything XHTML compliant. I put in the correct doctype, made everything lowercase, closed every tag, and put quotes around all attributes. Then once that was passing the W3C XHTML validator I added a style section to the header and started editing. (Normally I'd use an external CSS and link to it from my HTML but I figured I'd probably be e-mailing my resumé to people and didn't want them to have to worry about multiple files)

The one thing that I wanted to avoid was adding structure to my document just so that I could lay things out (i.e., I didn't want to add tables all over the place just for the sake of layout). Secondly, I wanted the document to still render properly if someone decided to turn off stylesheets entirely within their browser. So I introduced several div elements as containers so that I could style and position blocks of content. My document is pretty hierarchical so this was actually pretty simple and wasn't really breaking my rule about adding tags for layout. As I worked I needed to read a bit more about CSS topics I had only briefly touched on in the past (specifically, float, relative and absolute positioning). I also had to decide on some colours and fonts but I just used some of my favourite sites as templates for those choices.

In the end I have an XHTML/CSS standards-compliant document that looks good in Firefox, Mozilla, Camino, Internet Explorer, and Safari. The content and the visual appearance code is nicely separated, even if they are in the same document, and it serves as a nice little showcase for my appreciation for standards and my ability to apply them to a web application.

I got my first callback. Was it the content or the styling? Maybe a bit of both. ;-)

[Update: I forgot to mention that the Firefox "Web Developer" extension is a great tool for graphically viewing outlines around the structural element of your HTML document and for seeing what would happen if CSS, graphics, or other browser functionality were disabled]

Thursday, May 05, 2005

Foosball

Someone at our office brought in their own table about a month ago and I've found myself rediscovering the fun of foos. I've also found myself checking into the history of the game. I was quite surprised to learn that in foosball's heyday in the 70's people won cars (porche, corvettes) and quite a bit of money (there was a $1,000,000 tour at one point)!

I even started looking into possibly buying a table. I went down to the local dealer showroom (pool tables, foos tables, poker tables, video games etc) and the salesman there took some time to really show me what makes a good table and what the differences are as you move up in price. Quite the education (much more fun than C#). So I'm looking at a Tornado brand table. The Cyclone or the Storm. We'll see if my fascination with the game lasts long enough for me to plunk down the money...

So do you want to see an interesting video? Check this one out. It's for the Bonzini table not the Tornado. It's amazing to see how well someone can control a foosball.

NeoOfficeJ

I've been using OpenOffice for a couple of years now but the thing I dislike most about it, is that it runs under X11 and just doesn't look or feel like a Mac app. It looks all gray and Windows95-ish and worse, the command keys are all messed up. So I finally tried NeoOffice/J and I'm quite a bit happier. It still looks more like a Windows app than a Mac app BUT the menus are at the top where they should be and the command keys are correct. It's fast, the fonts look better, it has a double clickable application icon and it doesn't use X11. So far so good. And its free. :-)

PSync to the rescue

PSync is a little Perl command app written for Mac OS X that synchronizes two directories. Perfect for doing backups. I finally put my second drive to work as a backup volume. Now when the time is right I can upgrade to Mac OS X 10.4/Tiger and see for myself what all the good press is about.

Two weeks after my C# course

Well all that course really did for me was to get me to appreciate Java more. C# is a pretty good copy of Java but it seems that most of the differences/compromises from Java seem to be for supporting legacy Windows components. I don't think that's a bad thing necessarily but unless you have a huge pile of C++ or COM code lying around, I think the choice of Java or C# would be pretty difficult, especially if you're developing web apps. Afterall, why constrain yourself to one platform and one application server? Also having experienced the limitations of Visual Studio for a week, I know that code editing can be made way more efficient (yay Eclipse!).

I think the place where C#, .NET and Visual Studio shines is in the creation of rich client applications. Dot-NET leverages all the native Windows components so your apps look good and behave well. Rich client .NET apps, like Java apps, seem to take a little while to get going but once you're there you don't really know you're running a .NET app. I think if IBM ever gets their act together and make a decent SWT GUI editor then Java may (finally) be a contender on the Windows platform. But for now MS has this all to themselves

So what have I really done with my new knowledge? Well not much.
  1. I wrote a little application to interface with iTunes (which has a pretty full fledged COM interface). It just grabs the song title and artist of the currently playing track and throws it on the clipboard. Handy for sending someone an instant message.
  2. I also tried out ADO.NET with Mono. Mono ships with a driver for PostgreSQL. So I wrote a little command line app to connect, execute a query, and print out the results. Not too exciting but pretty easy.
  3. I spoke with the instructor about Object Relational Mapping and without any prompting from me, he suggested NHibernate. He's using it on his current project and says it works quite well. I really dig Hibernate so it's good to hear that C# developers can benefit from this technology as well.
  4. I tried to create a GUI using Windows.Forms on my Mac. That was a bust. Apparently it's possible but you have to install a bunch of other junk. I just wasn't that interested.
The next things for me is to probably find a gig where I can really exercise this thing called .NET...