Sunday, April 25, 2010

Off to a new stage

Lily and I at my thesis defense.

Tomorrow I start the next stage of my schooling. Today when someone asked how my grad career went and I replied, "It was fun," she looked shocked. It struck me then how blessed I am to have worked with such a great and supportive mentor on a project that allowed me to pursue my interests in translational and computational neuroscience all at once, an experience that can be summed up in none other than truly "fun."

It was sad to bid farewell to my Linux workstation, but I look forward to continued collaborations with Lily and the lab. For now, I'll be scrambling to shift my circadian rhythm forward while dredging up clinical skills from four years' past. At least I found my trusty old clipboard.

Thursday, April 22, 2010

apy 2.0 in the works!

I've (finally) had a chance to get started on updating Arthur's website to inaugurate the publication of his first book. Come follow the development on the beta site! Feedback welcome as usual.

UPDATE: One of the most fun parts about this round of development has been my discovery (finally) of jQuery, a clean API for incorporating a consistent set of JavaScript interactivity across platforms. And I just found out that the jQuery conference is none other than this weekend, in my backyard! (well, the Bay Area backyard.) Unfortunately it's already sold out, so here's looking to next year...

Wednesday, April 21, 2010

alpha3 out the door!

We're halfway into the NFL off-season, which means it's high time to make another tXtFL 2.0 pre-release (alpha3). This time I've focused on making the off-season the in-season with the ability to follow your fav team through a season in the football simulator. I don't know how much time I'll have in the near future to make full (pre-) releases, so it was nice to get this one out the door. In the meantime, I'll focus on incremental feature "pushes" via the new tXtFL Java Web Start mechanism, just to keep things interesting.

Happy tXtFL'ing!

Monday, April 19, 2010

Dial up!

This weekend I visited my brother in SoCal and was fortunate enough to tote along an old-school iPhone 2G. I must admit that traveling with an iPhone made the usual frustrations of travel such as airport waits or transfer downtimes unusually enjoyable. But most of the enjoyment came from the books I had downloaded onto my Barnes & Noble eReader and Amazon Kindle software for the iPhone. The dial-up-modem-like speeds of the original iPhone are nothing to brag about, and their main benefit was to help me appreciate the cable connection once back at home or to reminisce on the good ol' days of early college, when simply having a dial-up Internet connection was worth writing home about.

And speaking of college Internet, I came across a news article from today entitled: "Your fastest Internet in the world is found in Berkeley, CA":
Those three spots are Berkeley (average speed: 18.7Mbps), Chapel Hill, North Carolina (average speed: 17.5Mbps), and Stanford, California (average speed: 17.0Mbps).
There's something beautiful about a campus whose student-run computing facility rivals entire IT organizations from other other universities. Now if only San Francisco could connect the Bay Area campus triangle of Internet splendor...

Wednesday, April 07, 2010

Enabling Java Web Start

Some folks like to start their mornings with Java, but I like to start mine with Java Web Start.  What brew of coffee is that, you ask?  It's the kind that's now powering tXtFL, the football simulator written in the Java programming language.  With Java Web Start (JWS), launching a program is as simple as opening a browser page and clicking on a link.  JWS will identify the platform, download the correct files, and bring you to the football stadium in no time.  But as the road from tXtFL to JWS was considerably more arduous than I had hoped or intended, I'd like to take the liberty to describe how to JWS-enable a program, in hopes that it might help if you are planning to do the same.

Getting your John Hancock: signing JARs

The first step to enabling a program for JWS is to set up both the executable files and the files to execute them.  As much as I'd like to click on a link to open up a program, I also want to know whether that program has any security issues.  JWS gets around this problem by requiring files it launches to be signed, signifying who is the owner of those files.  Signing a file usually involves generating a key and then using that key to sign each of the files that will be downloaded by JWS.

The executable can be generated using a standard JAR command.  The command usually specifies a manifest file that identifies the main path, the name of the resulting JAR file, and the .class files and other supporting files necessary to run the program.  One of the tricks I've just learned is that JARs for JWS require neither the classpath nor the manifest file at all!  All of that information will be provided in a separate launch file.

Here's a jar example from tXtFL.  If you want the file to also be executable outside of JWS, you'll need to pass it a manifest file.

jar -cf tXtFL.jar com about.txt logo.png logo-draft.png draft

To sign the JAR, I needed to generate a key for signing.  The following command creates a key named keystore that will identify who I am using the information I provide it, including company name, etc:

keytool -genkey -keystore keystore -alias myself

Using this key, I can now sign the executable and all the other JAR files that the program requires.  tXtFL needs one of a number of SWT files plus the derby.jar database file, which can be individually signed using the appropriate version of the following command:

jarsigner -keystore keystore tXtFL.jar myself

For a more complete example, see the end of the tXtFL build script.

3-2-1...Liftoff: Setting up for launch

Now that the signed JARs are in place, I can generate the file to execute them.  JNLP files are the launch scripts that specify where the executable and support files are and how to access them.  The tricky thing is that the JNLP specifies where itself is--or should be.  JWS will always check this location and use the version there, regardless of whether it's an older version.  Be sure to check that "codebase" specification in the JNLP file if debugging is turning out to be a nightmare (more on that below).

The whole appeal of JWS for tXtFL lies in the platform-dependence of SWT, the underlying graphical toolkit for tXtFL.  This Eclipse-based toolkit affords many powerful features at the expense of requiring a separate toolkit to be distributed for each platform on which the program is expected to run.  Fortunately for us, JWS can automatically detect the platform and specify the appropriate version of SWT to download.  Detecting the platform is merely a matter of using the "resources" tag to specify both the "os" and the "arch".  That's right--JWS can detect not only whether the user is using a Mac or a PC, but also whether the computer is running a 32- or 64-bit of Java.  One huge source of confusion is that for Java, "32-bit" vs. "64-bit" refers to the version of Java, not necessarily that of the operating system.  JWS bypasses that confusion by doing the detection process for you.  Here's an example of the syntax:


<resources os="Mac OS X" arch="x86_64">
    <j2se version="1.6*" java-vm-args="-XstartOnFirstThread" />
    <jar href="lib/swt-mac64.jar" />
</resources>


Ain't that beautiful?  When JWS loads the JNLP file on a Mac running 64-bit Java, JWS learns that it should download the swt-mac64.jar file and also pass the -XstartOnFirstThread argument, a requirement for running SWT-based programs on the Mac.  Adding similar code for each of the other supported platforms allows custom arguments and resource files for each targeted platform.

Here's a complete example, from tXtFL.

Embedding a database (perfectly optional)

tXtFL had a unique problem on its hands, and that was the fact that deep in the bowels of tXtFL lies legacy code and legacy ways of doing things that longed for a dramatic overhaul.  As a lover of all things Text, I originally wanted to make sure that the player and team configuration files in tXtFL were composed of simple text files, one per player or team.  The end result was thousands of files that would be a nightmare to transmit over the web merely to play a simple game of football.  Of course, these files could be embedded into the JAR executable, but that would defeat the purpose of the text files in the first place since they would be buried rather than accessible in the executable.

As a long-term solution, tXtFL underwent a dramatic overhaul with the introduction of a shiny new Derby database.  Derby takes care of these configuration files by completely doing away with them (or almost, as you shall see).  Each player and team file becomes merely a line or several lines within the database.  The database is generated on the fly when the user first launches the program, and the database resides on the user's computer rather than requiring any additional transaction over the web.

Of course, one issue remaining is how to get the player and team data into the database in the first place.  The program still requires a player and a team spreadsheet containing all of the data.  Collecting the data in 2 files is certainly an improvement over the thousands of files previously used, but they still require the program to have a way to access files in the first place.  It turns out that the solution is rather simple: accessing files using the getResourceAsStream method allows the files to be embedded within the application jar.  Now the player and team spreadsheets are packaged right inside tXtFL.jar.

By default, a new Derby database will be instantiated in the working directory.  That's fine if the directory is where I'm testing the files, but becomes problematic when a user launches JWS from the browser, in which case Derby tries to write its files to the browser directory but fails because of permission errors.  The solution is to set the derby.system.home property to point the browser to a defined, accessible directory.

Testing tXtFL: Finding multiple platforms from which to test JWS

The first place I like to test my files is, of course, on the local system.  I always thought of JWS as an Internet-based solution, but it can also be configured to launch from the local computer.  I simply changed the codebase to point to the directory on my computer where I had stored the JWS files (eg file:///home/user/src/txtfl/), and JWS loaded the application files from there.  When I was ready to "go live," I copied the JWS files to my server and updated the codebase to the server URL.

When I first put the files onto the server and attempted to launch them, I got a page that displayed nothing more than the title and description of the application.  The server wasn't configured to tell the browser that the JNLP launch file is meant to be run by Java Web Start, so the browser tried to display the file as a web page.  Fortunately I'm hosting my pages through a Linux-based service that gave me access to configuring the server file type specifications.

Many folk on the web castigate the WORA principle of Java--"Write Once, Run Anywhere."  I think that everyone agrees that Java (or life) isn't quite that simple even at it's best, but it's a software principle that I for whatever reason have come to believe in.  I guess I like to be able to use my software regardless of whether I'm sitting at a Windows or a Linux or a Mac box, and I want whoever's using my software to have the same options.  Most importantly, I want everybody everywhere to be able to play virtual football whenever they can, football season or otherwise.