The Java repliers are right on the mark. Trying to use app-independent portability layers ensures apps of any complexity will suck. By "suck", I mean "compromised at every turn by lowest-common denominator design decisions". Your app will end up using threads on an O/S designed to make multi-processing beautiful (Linux), or end up using multiple processes on an O/S designed to make multi-threading beautiful (Windows). It'll be clueless about the nifty GUI features that exist on a Mac but not Windows, and vice versa. Knowing up front that your app is going to suck allows you to, in all good conscience, choose a language that highly adapted for creating apps that suck in this manner.
When I fire up a Java app on Windows (and I ALWAYS know it's a Java app the minute it finally manages to lumber onto the screen), I know I'm going to get the same sucky behavior if I fire that app up on a totally different platform (well, assuming I can manage to figure out whatever obscure infinite-megabyte downloads are needed to get the right "runtime engine" for the given app).
Really, the only way you can make your app suck even more and be even more portable is to just go ahead and make it a web "service". That has the added advantage that nobody really expects anything but poor performance and clunky UI design from the get-go. But if for some reason you can't have your app suck as bad as a web service, then Java is definitely the next-suckiest way to achieve that portability that your end users don't give a crap about, but you hope will make your life easier.