In my most recent blog, I took a look at whether or not you may need to consider writing your software in a cross platform portable fashion. In this blog, I will examine the various options for writing cross platform portable code. There are two ends to writing cross platform code: the interface, and the processing portion of the code. In a pure desktop application, they are contained within the same set of code. The front end is almost always some sort of GUI, or occasionally a command line. A server application tends to take input from a network socket, and produces output to another network socket, a database, a file, or a combination of the three. In a client/server situation (including dynamic Web sites), the front end communicates with a backend server application (ultimately via a network socket, but sometimes not directly) which in turn produces output which arrives over a network socket (again, not always directly).
No matter what type of application you are writing, you only have a few options in terms of how to go about writing cross platform code. Your first choice is to separate your presentation code from your logic, write the presentation in platform-specific code, and reference a library that you wrote to be portable. Your other choice is to use a language and interface toolkit that is portable.
Whichever route you take, part of your program will need to be written in a portable language. This is where the truly tough decisions come into play. Look back on what languages I consider to be highly portable: Perl and standard C/C++. These languages have their roots in the UNIX world, where portability is a concern. Perl has the advantage of being a high level, interpreted language; the language does not allow you to deal with anything that may be system-specific, and the interpreter handles any incompatibilities for you. Cross platform compatible C/C++, unfortunately, is rather limited in what you can and cannot do without delving into area where you will break its portability. Perl is a very good language to be working with, in and of itself, but it does not have the support of application servers like Java or the .Net languages have. C/C++ is just downright not nice to work with. Both Perl and C/C++ completely blow Java and .Net out of the water in terms of speed. I have not worked with Ruby, but knowing its properties, I think that it is fair to assume that it is also significantly faster to execute than Java, and has no cross platform compatibility problems either. There are also less popular (but still viable) alternatives such as Python, Lisp, O'Caml, and more.
What is a programmer to do?
I think that for a smaller project, it is possible to manage the incompatibilities amongst various JVM's and avoid application server specific code and use Java. For a larger project, I need to question this approach. For a large project, the current trend seems to be to just throw hardware at the speed issue. The common logic is, "hardware is cheaper than developers." I do not believe this to be true. Is it truly less expensive to maintain 500 servers than 400? The power bill alone is a small mint. Additionally, this logic assumes that development in Java or .Net is so significantly faster and easier than development in C/C++, Perl, Ruby, or whatever. When you are looking specifically at Web applications, Ruby on Rails and PHP also come into play. Personally, I am not a fan of PHP. I think development in it is downright miserable. But PHP does have better performance than Java, from what I have read. I cannot judge RoR at all, since I have not personally worked with it.
If you are working on a large application, it is impossible to ignore the performance factor. Hardware costs are ongoing; a well written application gets written once, and after the initial development, support and maintenance and new feature costs are a fraction of what the initial development costs were. It is my contention that for a large Web based application it is less expensive to spend a little bit more time, effort, and money working with Perl, Ruby, C/C++, or some other highly portable language in a CGI environment than to write slower, less efficient code in Java or .Net.
In addition, the advantages of Java or .Net quickly disappear when you need to start writing routines or functions outside of the core libraries. Perl, C/C++, and Lisp all have excellent support for a wide variety of scientific functions, AI, text parsing, and many other less mainstream applications. For a variety of factors, Java and .Net do not have these kinds of libraries, and the languages themselves do not lend themselves well to this type of development. If your application goes beyond basic C/R/U/D functionality, then your secret sauce is in the backend logic. Backend logic in Perl tends to take about 75% less lines of code than the equivalent logic in Java, VB, or C#, because Perl is a much more powerful language. This holds true for any functional programming language, in my experience. As soon as your program goes beyond gluing various libraries together with small dabs of code, the deficiencies of Java and .Net quickly become obvious. If your differentiating factor is going to come from advanced logic or high performance, Java or .Net just will not cut the mustard.
All said and done, writing cross platform coding is always a juggling act. There are no hard and fast rules to follow. How you decide to go about it is entirely dependent upon your needs. Java is a good choice for projects that do not need to scale much or require much business logic, but as the operational demands placed upon the software increase, and/or the amount of business logic increases, it is my belief that the additional effort of coding in Perl, C/C++, or a similar language more than pays for itself in terms of reduced hardware needs, faster execution, and less effort needed to write complex logic.