Archive for the ‘Programming’ Category

JavaOne 2007

I had the opportunity to go to the JavaOne conference two weeks ago, in San Francisco. It was quite an experience for me as I had never been to a technical conference before, let alone one of that size. I’m not exactly a Java enthusiast, but I am a Java developer. I spend most of my day writing Java code, so going to all the presentations about making better Java code, as well as interacting with Java developers from all over the world, was really educational.

I noticed a few things from the conference that I wanted to write down before I forgot. The first is that even in Java-land, scripting languages are hot. Lots of people were talking about JRuby, Groovy, JavaScript, JavaFX Script, and more. JRuby in particular was getting a lot of excitement from everyone who’s been hearing for the last couple years about how cool Ruby on Rails is. I’ve seen a lot of Rails demonstrations and they’ve failed to impress me but the Ruby language itself is very appealing, especially to someone like myself who mainly scripts in Perl or JavaScript. I’ve definitely been convinced to use Ruby for my next personal web app project, and the combination JRuby’s speed and native access to Java code will make me feel a lot better about it.

There were a lot of talks about static analysis tools, and FindBugs in particular. I’ve been using FindBugs on my Java code (and FxCop for my .NET code) for quite a while, but a few of the presentations gave me a much better idea of how powerful static code analysis can be. One of the best ideas is using special annotations that more clearly document the intended behavior of your code. Not only does this serve as additional documentation, it helps you design your classes better and helps out your code analysis tools. One of the first things I did when I got back was grab the latest FindBugs release and start sprinkling those magic annotations all over my code, and from now on I’ll be writing them in whenever I write new code.

I also got more in-depth exposure to the REST philosophy, which I had heard a lot about but not really thought about too much. I really like the idea, but until the tools get to the point where I can write up some sort of service description and generate client code like I can do with WSDL, I’m going to hang back a bit. Maybe WADL will catch on. I also got a better explanation of OpenID than I had gotten previously, and I’m really impressed. I like that it’s so simple, and that it can still integrate with technologies like CardSpace in a way that adds value to both sides. I searched for an open implementation of an OpenID provider that uses CardSpace, but it doesn’t look like any exist yet.

Another, less explicit theme at the conference was that the Java community has noticed the great design of C# and the .NET framework and are trying to fit some of that back into Java. I’ve always felt that C# was “Java done right”, and the number of JSRs (Java Specification Requests) that I saw for C#/.NET features is a testament to that. JavaSE 5 already added annotations (attributes), generics, foreach, enums, variable length arguments lists, and autoboxing, all features from C# 1.0 or 2.0. The stuff that’s being discussed for JavaSE 7 and beyond includes “superpackages” that look a lot like assemblies, continuations, a “using” statement, generics that don’t use type erasure, indexers, and switching on strings. I think this is great – C# made a lot of great improvements that were no doubt based at least in part on experience with Java, so it’s natural for Java to get back some of that. I didn’t see much talk of any of the C# 3.0 features like LINQ, object and list initializers, extension methods, etc. I did see some talk about incorporating lambda expressions, though, which would be pretty nice.

Despite the fact that the Java language has some catching up to do, one glaring advantage of Java over .NET became apparent to me while I was there. I’m not talking about the platform-independence advantage, though that is certainly there – I don’t think I could imagine building a large, scalable distributed service with Windows machines. No, what I’m talking about is the community. That’s not to put down the large and active .NET community, it’s just that the Java community is huge. And especially through open source, there’s just a lot more going on. I feel like a large part of this is that Sun and other Java leaders have been willing to incorporate the community’s best products into the standard toolset. Products like ant, Eclipse, Spring, JUnit, and even JRuby are accepted tools. Meanwhile on the .NET side, you’re basically taking whatever Microsoft gives you. And while that can usually be good, Microsoft runs the risk of ignoring the direction people are actually heading in.

In the end, I left the conference with much the same opinion of Java that I had in the beginning. Java is a tool, and a good tool, but not a particularly exciting tool. It does have some exciting features (I love JMX), and after my week in the Moscone Center, I feel like I can be more competent at creating Java-based software. Maybe I just haven’t worked on the right Java projects. I hope as my experience with the platform grows, I’ll be able to contribute more, either through this blog or through open-source projects. And who knows, maybe one day I’ll really feel like a Java Guy.

Setting the correct default font in .NET Windows Forms apps

I was working on XBList the other night when I realized something - the font used in its dialogs and the friends list wasn't Segoe UI. Segoe UI is the very pretty, ClearType-optimized new default dialog font in Windows Vista. In Windows XP and 2000, it's Tahoma, and in earlier editions it was Microsoft Sans Serif. You can see the subtle differences between them:

Microsoft System Fonts

In .NET and Windows Forms, the default font for controls is actually Microsoft Sans Serif, not the operating system's default dialog font! Kevin Dente explains this on his blog. This is not the only time Microsoft's dropped the ball on this - if you go through some dialogs in Vista you'll see that many of them use Tahoma or even Microsoft Sans Serif instead of Segoe UI. This is pretty funny, especially when Rule #1 of the Top Rules for the Windows Vista User Experience is "Use the Aero Theme and System Font (Segoe UI)". Mitch Kaplan offers up a pretty good explanation for why getting it all right is very hard, but having a mix of old and new fonts still looks shoddy.

I don't want my apps to look shoddy. Embarrassingly enough, I've been hardcoding Tahoma in all my apps to get the more "modern" XP look. Now that Vista's on the scene, it's clear that I want to select the correct default font for whichever OS my app is running on. As Kevin points out, Control.DefaultFont is no help here - it's what's driving Windows Forms' default choice of Microsoft Sans Serif in the first place. After some digging I found this Visual Studio feedback ticket (sign in required), where the Visual Studio guys explain that, while they couldn't fix the default, they did create a SystemFonts class to help out. They recommend putting this code in your Form's constructor:

C#:
  1. this.Font = SystemFonts.DialogFont;
  2. InitializeComponent();

Unfortunately, this doesn't work in a number of ways. The first is that on Vista, SystemFonts.DialogFont is... Tahoma! Closer, but not quite right yet. If you pop open SystemFonts in Reflector, you'll see that the DialogFont property just does some simple platform-detection, and then just hardcodes Tahoma. This worked when it was just 2000/XP vs. 9x, but Vista throws it for a total loop. Fortunately the fix is easy - use SystemFonts.MessageBoxFont instead. This one seems to always return the correct default dialog font.

However, I ran into one more problem. If I set the default font on the Form, like the code above does, I get weird, bloated controls:

Setting the default font on the form screws up controls

Fortunately I've got a solution for that one too. Instead of setting the font on the Form and letting it inherit, just loop through the Controls property, and individually set the right font on each control:

C#:
  1. // Set the default dialog font on each child control
  2. foreach (Control c in Controls)
  3. {
  4.     c.Font = SystemFonts.MessageBoxFont;
  5. }
  6.  
  7. // Use a larger, bold version of the default dialog font for one control
  8. this.label1.Font = new Font(SystemFonts.MessageBoxFont.Name, 12f, FontStyle.Bold, GraphicsUnit.Point);

Now I get a more familiar-looking dialog:

Setting the default font on each control looks fine

I could always make a subclass of Form to do this for me, but I'm OK with copying it into each new form. With this code, all my controls come up with the pretty new Segoe UI font in Windows Vista, and Tahoma in XP.

Using MyODBC with ASP.NET in IIS7 on Vista x64

That's a heck of a title, but it's a problem I hit recently. I have a bunch of ASP.NET sites that use MySQL as their datastore, but I hadn't tried the on IIS7 yet. It took a while to get them to work at all (I had to set permissions on web.config and the other website files so that they could be read by both the Users group and the IIS_IUSRS group), but then I was left with an error about my MySQL connection. "ERROR [IM002] [Microsoft][ODBC Driver Manager] Data source name not found and no default driver specified" - another very general error that basically means "Something is wrong with your ODBC driver, somewhere."

After some searching, I learned two things. The first is that if you're running 64-bit you can't use the standard ODBC Data Source Administrator in Administrative Tools with MySQL. You've got to go to C:\Windows\SysWOW64\odbcad32.exe and set up your DSN, if that's your thing. The other thing is that the MyODBC driver is 32-bit only. So to use it at all, you need to make sure you're calling it from 32-bit apps only. That means you've got to tweak the Application Pool you're using to run all its ASP.NET applications as 32-bit. To do this, go to Administrative Tools > Internet Information Services (IIS) Manager (or just hit the Windows key and type "IIS"). Then go to "Application Pools" and select whichever application pool your ASP.NET app uses (or create a new one just for your MySQL apps. Click "Advanced Settings..." and set "Enable 32-Bit Applications". Now the AppPool will use the 32-bit .NET CLR to run your app, and it'll be able to see your MyODBC driver (whether you use a DSN or not).

IIS7 32-bit Application Pool

Installing Aptana on Windows Vista with Aero Glass

I've recently given up Dreamweaver entirely in favor of Aptana, a great (and free!) Eclipse-based web development IDE. It features great JavaScript IntelliSense, document outline view, AJAX library function autocomplete, and an FTP component that should make Dreamweaver users very comfortable. Even better, with plugins like Subclipse, you get source control for your websites. Basically, it's one of my favorite programs.

However, all is not rosy. The Aptana documentation's guide to installing and running Aptana on Windows Vista recommends turning on XP compatibility mode, disabling desktop compositing, and always running it as Administrator. If you haven't had an app turn off Aero Glass for you before, you're in for a shock - it really sucks after you've gotten used to Glass. And running as Administrator isn't that great an idea with a product as connected as Eclipse.

Fortunately, all is not lost. First, go to Sun and download the JavaSE 6 JRE (32-bit). It's a huge upgrade from the Java 1.4.2 JVM that Aptana usually comes with, and it includes some major Vista compatibility features. Next, download and install Aptana minus the JRE from the Aptana downloads page. Already installed Aptana? Just go into the program directory and delete the "jre" folder. Now, make sure the Aptana shortcut doesn't have any compatibility features checked. (Disclaimer: you might actually need to run as Administrator the first time you use Aptana, but certainly never again.) Start up Aptana, and everything should be glassy and smooth.

Aptana with Aero Glass

If Aptana complains that it can't find the JRE, go into your Aptana program directory and open up aptana.ini. Add the line -vm='C:\Program Files (x86)\Java\jre1.6.0\bin\java.exe' to the top of the file, and save it. I had to do this mainly because I have both the 64-bit and 32-bit JREs installed, and while most Java apps work on the 64-bit JRE, Eclipse (and thus Aptana) doesn't support 64-bit yet.

Update: Newer versions of Aptana come with Java 1.6, so this isn't a problem anymore.

Creating nested custom configuration sections in ASP.NET 2.0

This weekend I decided to go through the hodgepodge of common code that's shared between a lot of my ASP.NET websites and refactor it a bit. I'd only just learned about the magic of HttpModules and HttpHandlers, and I immediately saw a lot of canidates in my copy-paste code and global.asax handlers where a HttpModule would be a better solution. One of these was the code I was using to redirect old pages to new pages whenever I moved them. For example, at some point I had moved http://www.numbera.com/rome/tools.aspx to http://www.numbera.com/rome/tools/, and I wanted anyone who visited the old URL to get redirected to the new one. Previously, I just had some code in global.asax that hooked Application_OnError, checked to see if it was an HttpException (a 404 file not found, specifically), and then redirected if it knew where the file really was. Pretty simple, but not very general. So I broke it out into an HttpModule that basically did the same thing, but no longer required me to cut and paste code into my global.asax. However, one improvement I wanted to make was to allow for configuration through my web.config file, instead of having to hardcode an if/else tree for each redirect. I basically wanted to have a section in my web.config like this:

XML:
  1. <configsections>
  2.     <sectiongroup name="brh.web">
  3.        <section name="redirectOldUrls"
  4.          type="Brh.Web.RedirectConfigurationHandler, Brh.Web.Utility"
  5.        />
  6.    </sectiongroup>
  7.   </configsections>
  8.  
  9.   <brh .web>
  10.     <redirectoldurls>
  11.       <redirect filePattern="tools.aspx" url="~/tools/" />
  12.       <redirect filePattern="strategy.aspx" url="~/strategy/" />
  13.         <redirect filePattern="military_people.aspx" url="~/people/" />
  14.         <redirect filePattern="history.aspx" url="~/history/" />
  15.         <redirect filePattern="teacher.aspx" url="~/teacher/" />
  16.     </redirectoldurls>
  17.   </brh>

(more...)