Cover V10, I07


Why Java Isn't Appropriate for Everything

Adam Ronthal

In today's technology landscape, many companies, from brand-new startups to established corporations, feel a strong need to be "buzzword-compliant". This often leads to the inappropriate application of undeniably powerful and exciting new technologies. A recent example of this trend is the indiscriminant proliferation of Java.

Not that I have anything against Java, mind you. On the contrary, as a senior systems engineer, one of my primary responsibilities is maintaining a highly available Application Service Provider (ASP) platform that runs -- you guessed it -- Java servlets within a J2EE platform. Java and the J2EE standard allow a wide choice of development platforms, deployment platforms, and compliant application servers for our production environment. It allows us not to be locked into specific vendors and has made us more efficient in the long run.

That said, of course, there is a time and a place for everything. Although Java delivers the "write once, run anywhere" capabilities that serve our engineers (and us operations folks, too), it simply is not the appropriate tool for everything.

The very premise of "write once, run anywhere" has radically changed the composition and make-up of engineering organizations. The choice of development platforms used to be dictated by the ultimate deployment platform for the product or service being developed. If you were writing applications to be deployed on Solaris, you developed on Solaris; if you were writing Windows applications, you developed on Windows. The practical outcome of this was that software developers necessarily gained a solid understanding of their underlying development platform at the systems level, instead of just the application or code level.

Java circumvents all of this. Today, it is not uncommon for the bulk of product development to occur on Windows NT when the final deployment is to be on Solaris or some other flavor of UNIX. From a pure Java perspective, it no longer matters what platform you develop on, as long as your Java Virtual Machine (JVM) is consistent and compatible with your production environment. Java engineering organizations often use NT as a platform for their developers for a number of reasons. NT boxes are more end-user maintainable, allow for the isolation of a development environment, and are cheaper than most UNIX workstations (open source operating systems like FreeBSD and Linux notwithstanding). Besides, it's easier to find Windows Java developers than UNIX Java developers, and most of the time, it doesn't make a difference.

In such a situation, it is critical that systems engineers be involved in the development process. Many tasks must be performed in a production environment that aren't necessary in a development environment -- especially a Windows development environment. As systems engineers, we have a responsibility to ensure a high level of performance for our production systems. In doing so, it is important that we apply and enforce some common sense when deploying and implementing specific features. It might be that Java is a good tool for the job, and if your engineering organization is a Java shop, you can bet that that will be the initial path of investigation. Often, however, the task at hand can be accomplished more efficiently in other ways, and Java would just be a resource hog.

"To a man with a hammer, every problem is a nail." -- Japanese proverb

Would you use a flamethrower to light a cigarette? Neither would I. Nor would I go to the trouble of writing a Java program to do tasks that would more easily and efficiently be accomplished by a shell script or perhaps a Perl program. When was the last time you ever saw a production-quality shell script suck up all the memory or CPU cycles on one of your systems? It happens to an overloaded JVM all the time.

The following examples document some real-world situations in which Java was proposed as a solution to an existing problem. In some cases, the use of the Java application was appropriate. In others, it was not. In still others, Java was imposed by a third-party vendor, leaving little choice to the systems engineer.

Case Study #1: Optimizing a High-Volume Web Site for Load

The easy way to optimize a high-volume, consumer-facing Web application is to pre-render those pages that are the same for all users and serve these pages directly from the Web server farm or some other distributed architecture like Akamai or Mirror Image. This greatly reduces the load on application servers and database servers, allowing them to focus on rendering those pages that are more highly personalized.

To do this, it is necessary to pre-render the "anonymous" pages and make them available to the distribution points on a regular basis. This strategy has worked very well in a portal application that I've worked on for the past few years.

Coming from this Java shop, the first version of the code for pre-rendering these anonymous pages was a Java application that could be run from the command-line to do an HTTP GET on the production site at regular intervals. Since there were many versions of the anonymous pages, approximately 70 HTTP requests were required, thus requiring 70 instantiations of a Java Virtual Machine. As the load on our systems and the number of pages to be generated increased, the pre-rendering job became more and more inefficient, using up more system resources for longer periods of time.

Perl plus LWP proved to be a viable alternative, but we ultimately used wget from the Free Software Foundation's GNU project -- a lightweight application compiled specifically for the target environment -- to do the same work much more efficiently.

In this case, Java was a completely inappropriate tool for the job at hand. With a little bit of preliminary thought and investigation, it would never have been used.

Case Study #2: Graphics Manipulation

As systems administrators and engineers, we must be concerned not only with the performance of our production systems, but also with the security implications of any feature or tool we are asked to implement.

Several months ago, one of our engineers came to me with an implementation of a new feature destined for our production site. The task at hand was a simple one. We needed to generate a gif image from a text-based feed and make it available on the production Web site with regular updates.

The proposed implementation used Java's Abstract Window Toolkit (AWT). Unfortunately, this implementation required that an X display be available at all times to perform the required rendering. This would have required one of our systems to be constantly logged in with X running and appropriate access to the application server machines where this was to run. I rejected the implementation on both efficiency and security grounds, suggesting the use of more systems-friendly tools -- in this case, Perl and ImageMagick.

The final implementation was fast, efficient, and secure. It also required a much deeper understanding of the more traditional systems-level tools -- shell scripting and Perl -- and was implemented by a systems engineer, not a Windows Java developer.

Case Study #3: Java and Third-Party Applications

As systems engineers, we are often asked to deploy third-party tools to help us implement new features on production servers. Some of these tools provide news or weather feeds; others provide product managers and marketing folks with select content for our portals.

One such tool from a popular provider of content feeds is a Java application with a browser-based interface that lets users select and edit content that will ultimately be displayed on our production site. To accomplish this, the tool incorporates a primitive Web server. Unfortunately, this re-implementation of a well-understood technology does not allow me to do things that Web servers were doing 5 years ago. I can't run SSL, run the server on a privileged port as a non-root user, or implement many other basic Web server features.

Is this an appropriate use of Java? Well, perhaps the application itself is, but I'd love to be able to run it as a servlet within the framework of a Java application server, or even a Web server. These days, many advanced Web servers have the capabilities to run Java servlets natively. By incorporating the application in a Web server or application server environment, the vendor could take advantage of today's robust, stable application server and Web server platforms. None of the Web servers I run in production need to be restarted on a daily basis to ensure that they don't hang.

The use of Java for the application in this example is not problematic; the implementation and deployment requirements are.

Case Study #4: The Java "Upgrade"

For more than a year, one of our providers of content allowed us to use rsync to manage the content feeds. It was easily scriptable, and thus easily added to the appropriate crontabs. It also ran with little or no maintenance. In short, we were very happy with the stability, reliability, and flexibility of the application. The rsync application is fairly lightweight, and has the added benefit of being compiled natively for the deployment platform, Solaris.

Recently, the provider has required all customers to upgrade to a new Java-based application to manage content feeds and will no longer support the rsync platform.

The new Java version is significantly more fully featured than the corresponding rsync version. Some of the new features save us the rather complex process of parsing and reformatting the feeds that we received through the use of XSL templates, thus making our content feed environment easier to manage and more efficient. The Java implementation is easy to maintain, is stable, and requires very little day-to-day maintenance.

Was the Java upgrade appropriate in this case? Overall, I'd say yes. The implementation was done in a systems-friendly manner, and the benefits of the new features far outweigh any costs of replacing the well-established rsync tool. The lesson here is that it's important to thoroughly evaluate such tools from a technical perspective. They may be Java gems that will improve your overall efficiency.

Case Study #5: Java-Based
Management Tools

One of the most common uses for Java is to provide a GUI management interface to a given application. The benefits to the vendor are many. One version of the management application will run on any platform with a JVM -- UNIX, Windows, even Macintosh. Unfortunately, most Java GUIs are slow, unstable, and require a lot of RAM to run efficiently. Depending on the implementation, there may be other limitations as well.

Our Application Server ships with a very well-designed Java-based management console developed using Swing. It provides a fantastic degree of functionality with a very pretty GUI. Regrettably, the capability to script some of these great features is practically nonexistent. Here, the need to build a GUI, easy-to-use management tool completely overshadowed the need to build a management tool that is more useful in a production environment.

Let's consider our target market. Although NT makes an adequate development environment, I suspect that the majority of high-performance Web sites with the need for a high-end Java application server deploy on one of the more popular flavors of UNIX. While most UNIX engineers appreciate a GUI interface for certain tasks, when it comes down to production systems work, we want powerful, scriptable command-line tools. If I'm running multiple JVMs spread across multiple systems, I need a scalable way to manage them. To many of us, scalable means scriptable. An additional limitation in this case is that the Swing GUI communicates through the Java RMI -- effectively barring me from communicating in any reasonable manner through our firewall, even using a VPN client. This effectively removes any chance of remote management capabilities, and is thus inappropriate for a production environment.

It is critical that vendors devote their resources to the development of production tools designed to meet the needs of production environments. A GUI should not be required for any kind of production work, from installation to ongoing management.

I'm Really Not Anti-Java

Java offers a remarkable platform for situations where multiple platform support crucial. It's a wonderfully full-featured language, increasingly robust, and unquestionably powerful. I highly recommend it for large software development efforts.

Because the proliferation of Java has led to fewer and fewer software developers with a solid systems background, it is critical that system engineers and system administrators take an active role in their organization's development practices to ensure the appropriateness of tools developed and designated for production systems.

Adam Ronthal is a senior systems engineer at Internet startup Verilytics, Inc. He currently lives in Cambridge, MA and can be reached at: