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: ronthal@fugue.net.
|