While the Java VM shields most developers from having to think about the
memory-management aspects their Java objects, the VM does not completely manage
other types of resources automatically, says Gwyn Fisher, CTO of Klocwork in
this interview with Artima. Great Java developers learn to understand exactly what
the JVM does, and does not do, for their objects.

There has been much discussion lately about code quality in Java. Most
developers would agree that the JVM provides an excellent infrastructure for
high-quality code, because it defines a uniform execution model across
operating systems and because of its automatic garbage collection
capabilities.

The notion that the JVM somehow takes care of all aspects of resources
management have become wide-spread in the Java community, says Gwyn Fisher, CTO
of static analysis tool maker Klocwork. While the VM does a good job managing
resources for Java objects, it's not designed to take care of all aspects of
resource allocation and de-allocation. When developers neglect to think through just
what the VM does, and does not do, for their objects, coding errors result:

Why do so many developers still think it's reasonable to create code that doesn't work?In some ways, it has become cheaper to deal with failure. What's the worst that happens? You just restart your Web server. You may even try to mask failure with some form of redundancy. Provided that you can make that work, software failure is no big deal, some would say.

In the real world, however, software failure is a very significant problem. To bring your own denial-of-service attacks right into your own code, to accept to live with a relatively low-quality code base, is less and less acceptable as the software we write goes onto devices, cell phones, or something that even gets implemented in your body.

In all of those interaction points, it is no longer acceptable for your
software to crash. The notion of consumer brand identify and consumer
acceptance of things also changes how we perceive software quality: If a device
you bought crashes every so often, it's only a matter of time before you return
it. If your consumer-facing Web site performs poorly, or needs to be
periodically restarted, that is going to negatively affect your brand
image.

In the Java space, the notion that you didn't have to worry about failure
has become especially prevalent, because the Java language is so forgiving of
runtime errors. And it's very nice to operate within an abstraction such as the
JVM.

The JVM takes care of you in so many ways that you get used to the mentality
that you don't have to worry about much at all. The problem is, there are
edge-cases where the JVM isn't really taking care of you. Most people are
building JVMs on other software, the OS, which is on hardware. At the end of
the day, you're still dependent on that middle slice of the cake.

For example, relatively few [Java] developers understand that if they don't
close a socket, the JVM is going to garbage-collect objects, but in the
underlying operating system, the socket at the OS level, that never goes away.
The JVM may manage the memory for you, but it often doesn't manage other
resources that your code has consumed.

That gets worse and worse the higher up in the stack you go in terms of
language abstractions. We try to stay out of the debate between dynamic and
statically typed languages. But how many developers in dynamic languages
really, fundamentally, understand what's going on in terms of resource
consumption and use? At the end of the day, you as a developer are responsible
for knowing what's going on.

Tools can really help in that environment. We provide a static analysis
tool, for example. We have our own compilers. Instead of Java bytecode, the
output of our compiler is a database. We can then analyze that database for
behavior, including erroneous behavior. We provide checks for about 175
different kinds of problems, and support Java, C and C++ out of the box.
Especially in a real-time environment, there is a lot of mixed code, not
one-hundred percent Java.

The difference in focus between the C/C++ and Java platforms couldn't be
more pronounced. Between our C and Java environments, we have roughly the same
number of code check rules. In C and C++, the checks we're performing are very
dependent on the code you write: We're really worried about null pointers and
memory leaks, and buffer overflows, and things of that nature.

In Java, there's a handful of Java language checks. But what you often don't
get right are the things you're dependent on, all the framework interaction,
the platform interaction, the Web server interaction. You almost never get that
stuff right the first time. The vast majority of the Java checks in our product
are all platform and framework interactions checks, not language checks: "Did
you close that socket? Did you close that SQL connection? You're injecting a
String into something you probably don't want to."

If you look at the productivity improvements of Java, you don't have to
worry about the language you're writing in any more. The beautify of Java is
there is so much code out there that you can pick up and use in your projects.
But you often don't know what that code is doing, how that code behaves in the
environment and, by extension, how your code interacts with the environment.

The single most important thing you can do as a developer, is to
fundamentally understand what the objects you're dealing with actually are,
what they actually do, think about them as a C developer would have to think
about them. Think about what those objects are doing under the covers, and in
terms of the platform and the operating system, and in terms of hardware
resources. Try to think about them as a piece of hardware: What is that thing
going to do? If you don't switch it off, what is going to happen?

You can be a good Java developer and never worry about that stuff. Thinking
outside the JVM is the important thing for a great Java developer. To
be a great Java developer, you have to understand what the JVM is doing for
you.

To what extent do you agree with Gwyn Fisher that great Java developers need
to think about the interaction between the JVM and their environment, and about
how the JVM interacts with Java objects?

Resources

About the authors

Frank Sommers is Editor-in-Chief of Artima Developer. He also serves as
chief editor of the IEEE Technical Committee on Scalable Computing's
newsletter, and is an elected member of the Jini Community's Technical Advisory
Committee. Prior to joining Artima, Frank wrote the Jiniology and Web services
columns for JavaWorld.