Wednesday, January 13, 2010

Caution: Double to BigDecimal in Java

The combination of Java's large worldwide developer base and easily accessible online API documentation has led to a generally thorough and accurate documentation of the Java SE API. There are still corners that might not be as thorough or accurate as one would like, but the API documentation is generally pretty good both in terms of thoroughness and accuracy.

Although the Javadoc-based API documentation has become pretty useful, we developers are often in such a hurry and often feel so confident in our own abilities that it is almost inevitable that we will sometimes continue to try to do things without first reading the manual. Because of this tendency, we can occasionally get burned by misusing a particular API despite the documentation warning us not to (mis)use it that way. I discussed this in my blog post on Boolean.getBoolean(String) and highlight a similar issue in this post related to use of BigDecimal's constructor that accepts a double.

At first sight, it might appear that the BigDecimal constructor that accepts a Java double would hold it with its originally specified precision in all cases. However, the Javadoc message for this constructor explicitly warns, "The results of this constructor can be somewhat unpredictable." It goes on to explain why (the double cannot hold the exact precision and this is made evident when passed to the BigDecimal constructor) and to suggest that the alternative constructor accepting a String as a parameter be used instead. The documentation also proposes using BigDecimal.valueOf(double) as the preferred way to convert a double or float to a BigDecimal.

The following code listing is used to demonstrate these principles and a few related ideas.

DoubleToBigDecimal.java

import java.math.BigDecimal;
import static java.lang.System.out;

/**
* Simple example of problems associated with using BigDecimal constructor
* accepting a double.
*
* http://marxsoftware.blogspot.com/
*/
public class DoubleToBigDecimal
{
private final static String NEW_LINE = System.getProperty("line.separator");

public static void main(final String[] arguments)
{
//
// Demonstrate BigDecimal from double
//
final double primitiveDouble = 0.1;
final BigDecimal bdPrimDoubleCtor = new BigDecimal(primitiveDouble);
final BigDecimal bdPrimDoubleValOf = BigDecimal.valueOf(primitiveDouble);
final Double referenceDouble = Double.valueOf(0.1);
final BigDecimal bdRefDoubleCtor = new BigDecimal(referenceDouble);
final BigDecimal bdRefDoubleValOf = BigDecimal.valueOf(referenceDouble);

out.println("Primitive Double: " + primitiveDouble);
out.println("Reference Double: " + referenceDouble);
out.println("Primitive BigDecimal/Double via Double Ctor: " + bdPrimDoubleCtor);
out.println("Reference BigDecimal/Double via Double Ctor: " + bdRefDoubleCtor);
out.println("Primitive BigDecimal/Double via ValueOf: " + bdPrimDoubleValOf);
out.println("Reference BigDecimal/Double via ValueOf: " + bdRefDoubleValOf);

out.println(NEW_LINE);

//
// Demonstrate BigDecimal from float
//
final float primitiveFloat = 0.1f;
final BigDecimal bdPrimFloatCtor = new BigDecimal(primitiveFloat);
final BigDecimal bdPrimFloatValOf = BigDecimal.valueOf(primitiveFloat);
final Float referenceFloat = Float.valueOf(0.1f);
final BigDecimal bdRefFloatCtor = new BigDecimal(referenceFloat);
final BigDecimal bdRefFloatValOf = BigDecimal.valueOf(referenceFloat);

out.println("Primitive Float: " + primitiveFloat);
out.println("Reference Float: " + referenceFloat);
out.println("Primitive BigDecimal/Float via Double Ctor: " + bdPrimFloatCtor);
out.println("Reference BigDecimal/Float via Double Ctor: " + bdRefFloatCtor);
out.println("Primitive BigDecimal/Float via ValueOf: " + bdPrimFloatValOf);
out.println("Reference BigDecimal/Float via ValueOf: " + bdRefFloatValOf);

out.println(NEW_LINE);

//
// More evidence of issues casting from float to double.
//
final double primitiveDoubleFromFloat = 0.1f;
final Double referenceDoubleFromFloat = new Double(0.1f);
final double primitiveDoubleFromFloatDoubleValue = new Float(0.1f).doubleValue();

out.println("Primitive Double from Float: " + primitiveDoubleFromFloat);
out.println("Reference Double from Float: " + referenceDoubleFromFloat);
out.println("Primitive Double from FloatDoubleValue: " + primitiveDoubleFromFloatDoubleValue);

//
// Using String to maintain precision from float to BigDecimal
//
final String floatString = String.valueOf(new Float(0.1f));
final BigDecimal bdFromFloatViaString = new BigDecimal(floatString);
out.println("BigDecimal from Float via String.valueOf(): " + bdFromFloatViaString);
}
}


The output from running the above code is shown in the next screen snapshot.



As the output above indicates, the problem of casting float to double prevents one from retaining the desired precision when passing a float directly to the BigDecimal.valueOf(double) method. A String can be used as an intermediary to accomplish this shown in the example and as demonstrated in similar fashion in Converting Float to Double in a Not So Common Way.

Note that Groovy's heavy implicit use of BigDecimal changes the game a little bit when using Groovy and dynamic typing. I may touch on that in a future blog post. For more details on floating-point issues (and I emphasize "details"), see What Every Computer Scientist Should Know About Floating-Point Arithmetic.

Monday, January 11, 2010

Software Engineering One of 2010's Best Jobs

I have recently had several colleagues and friends with the Systems Engineer job title brag (trying to convince themselves, no doubt) about Money magazine ranking Systems Engineer their #1 job in Best Jobs in America 2009. That same article ranked Information Technology Program Manager as #5, Computer/Network Security Consultant as #8, Software Developer as #12, Software Product Manager as #16, IT Business Analyst as #17, Technical Writer as #28, Computer Software Program Manager as #39, and Application Systems Analyst as #40. As this list demonstrates, many jobs related to software development were listed in the top 50 jobs in the United States.

In The Register article Software engineer rated best job of 2010 (almost), Gavin Clarke highlights the job of "Software Engineering" ranking #2 in The Wall Street Journal's Best and Worst Jobs 2010 (Actuary was #1) based on a CareerCast.com study.

There are numerous other software development-related jobs listed in CareerCast's Best and Worse Jobs 2010. Besides the #2 listing for Software Engineer, other examples are Computer System Analyst at #3, Web Developer at #15, and Computer Programmer at #34. The worst of the 200 is that of the roustabout.

One of the observations one cannot help but make when looking at these lists is the attempted delineation of various similar-sounding professions. There are already numerous blog posts and forum threads examining what makes a software engineer different than a computer programmer and so forth, so I won't go into that here.

The CareerCast.com page The 10 Best Jobs of 2010 provides a brief description of the job duties of a "software engineer" and points out that what particularly sets this occupation apart is its "hiring outlook":
With low unemployment compared to the national average and projected job growth of nearly 45% through 2016, Software Engineer currently has the best hiring outlook of any available job in 2010.


After a difficult worldwide economy has had a tremendous negative impact in the world of software development, it is encouraging to see positions in this field ranking so high in these studies.

The Systems Engineers may have had the #1 position in 2009, but that was so 2009. We Software Engineers have the highest ranking of related fields in 2010. Take that, Systems Engineers.

I now go to ensure that my resume refers to my current position as "Software Engineer."

Friday, January 8, 2010

Favorite Development Cheatsheets

Although modern search engines have made it easier than ever to look up various details, it is still sometimes nice to have a go-to resource to refresh my memory about certain development tasks. I first started to appreciate materials like this when I encountered the famous Oracle data dictionary wall posters (such as this TUSC-provided poster and the Quest poster). In this blog post, I point to and briefly summarize some of my favorite development-related cheat sheets.

There are too many useful DZone-provided Refcardz ("Free Cheat Sheets for Developers") to cover them all here, but I will focus on a few individual examples of them in this blog post. I call them out here separately because there are so many of them on so many different subjects. These require registration with DZone/JavaLobby, but that is free. Although I only list a small sample of these DZone refcardz in conjunction with other development-related cheat sheets listed in this post, it should still be obvious that a single free registration with DZone to be able to download so many useful cheat sheets doesn't seem so onerous.


Java Cheat Sheets

Java Collections

Java Collections Cheatsheet

When I was first learning Java in the mid- to late- 1990s, I wished there was a good visual summary of the different Java collections. Java collections have changed dramatically since then and increased in size and variety and so such a visual summary is even more desirable now. Coder-Friendly has made just such a thing available in the Java Collections Cheatsheet. Not only does this show collections-related hierarchical information and Big O notation for various operations on the various collections types, but it is also inspired by one of my favorite intermediate to advanced Java books (Java Generics and Collections).


General Java

Java Quick Reference
Java 1.5 Cheat Sheet
Java Reference Sheet

Jialong He's Java Quick Reference and Project Encycode's Java Cheat Sheet seems a little dated now, but can still be useful for a quick perusal of Java basics and overview of some of the JDK's packages. Pete Freitag's Java 1.5 Cheat Sheet adds some specific new features of J2SE 5.


Java Persistence API

Getting Started with JPA
TopLink JPA Annotation Reference

Mike Keith's DZone-provided (Refcardz #22) Getting Started with JPA provides an introduction to JPA and a good resource of the JPA basics. The TopLink JPA Annotation Reference is also helpful when developing with JPA.


XML in Java

Using XML in Java

The DZone refcardz Using XML in Java (#35) is written by Masoud Kalali and


Groovy Cheat Sheets

Groovy Refcardz

Although Dierk König's DZone-provided DZone Groovy Refcardz (#15) requires (free) registration, it is significantly more up-to-date (2008) and comprehensive (7 pages) than the 2004 Groovy Reference Summary.


Flex / AIR Cheat Sheets

Very First Steps in Flex
Getting Started with BlazeDS
AIR Cheat Sheets

Very First Steps in Flex is written by Bruce Eckel and James Ward and is available as a DZone Refcardz. Getting Started with BlazeDS is also a DZone refcardz (#75) and is written by Shashank Tiwari. The AIR Cheat Sheets do not require any registration to download the PDF.


Other Web Development

HTML

Core HTML

The DZone-provided Andy Harris Refcardz Core HTML (#64) covers HTML and XHTML along with brief mention of HTML 5 and Cascading Style Sheets.

HTML 5 Cheat Sheet (PDF)

Speaking of HTML 5, the HTML 5 Cheat Sheet (AKA HTML 5 Quick Reference Guide) from Chris Hanscom and Smashing Magazine summarizes this emerging standard's markup tags.

CSS

Core CSS: Parts I, II, and III

Speaking of CSS, there is a whole DZone Refcardz series written by Molly E. Holzschlag dedicated to CSS: Core CSS: Part I (#19), Core CSS: Part II (#25), Core Css: Part III (#34).

Veign's CSS3 Quick Reference Guide

If you are not registered with DZone (and refuse to do so), you can download the CSS3 Quick Reference Guide from Veign and Chris Hanscom without registration.

Thursday, January 7, 2010

Viewing Groovy Application's Classpath

Because the set of classes that Groovy applications see is wider than the set standard Java applications see, it can be helpful to see what classes are already on the Groovy classpath. This is very easy to do and the one line of executable Groovy to do this is shown in the next code listing.


#!/usr/bin/env groovy
this.class.classLoader.rootLoader.URLs.each{ println it }


The above code takes advantage of the Groovy RootLoader. This RootLoader is often used to dynamically add a library to the Groovy application's classpath, but, as the example here shows, can also be used to see what Groovy sees.

When the above code is executed, the results shown next are seen.


file:/C:/java/examples/groovyExamples/displayGroovyClasspath/./
file:/C:/Program%20Files/Java/jre6/lib/ext/QTJava.zip
file:/C:/Program%20Files/Groovy/Groovy-1.7.0/lib/ant-1.7.1.jar
file:/C:/Program%20Files/Groovy/Groovy-1.7.0/lib/ant-junit-1.7.1.jar
file:/C:/Program%20Files/Groovy/Groovy-1.7.0/lib/ant-launcher-1.7.1.jar
file:/C:/Program%20Files/Groovy/Groovy-1.7.0/lib/antlr-2.7.7.jar
file:/C:/Program%20Files/Groovy/Groovy-1.7.0/lib/asm-3.2.jar
file:/C:/Program%20Files/Groovy/Groovy-1.7.0/lib/asm-analysis-3.2.jar
file:/C:/Program%20Files/Groovy/Groovy-1.7.0/lib/asm-commons-3.2.jar
file:/C:/Program%20Files/Groovy/Groovy-1.7.0/lib/asm-tree-3.2.jar
file:/C:/Program%20Files/Groovy/Groovy-1.7.0/lib/asm-util-3.2.jar
file:/C:/Program%20Files/Groovy/Groovy-1.7.0/lib/balloontip_2009-01-2.jar
file:/C:/Program%20Files/Groovy/Groovy-1.7.0/lib/batik-anim-1.7.jar
file:/C:/Program%20Files/Groovy/Groovy-1.7.0/lib/batik-awt-util-1.7.jar
file:/C:/Program%20Files/Groovy/Groovy-1.7.0/lib/batik-bridge-1.7.jar
file:/C:/Program%20Files/Groovy/Groovy-1.7.0/lib/batik-codec-1.7.jar
file:/C:/Program%20Files/Groovy/Groovy-1.7.0/lib/batik-css-1.7.jar
file:/C:/Program%20Files/Groovy/Groovy-1.7.0/lib/batik-dom-1.7.jar
file:/C:/Program%20Files/Groovy/Groovy-1.7.0/lib/batik-ext-1.7.jar
file:/C:/Program%20Files/Groovy/Groovy-1.7.0/lib/batik-extension-1.7.jar
file:/C:/Program%20Files/Groovy/Groovy-1.7.0/lib/batik-gui-util-1.7.jar
file:/C:/Program%20Files/Groovy/Groovy-1.7.0/lib/batik-gvt-1.7.jar
file:/C:/Program%20Files/Groovy/Groovy-1.7.0/lib/batik-parser-1.7.jar
file:/C:/Program%20Files/Groovy/Groovy-1.7.0/lib/batik-script-1.7.jar
file:/C:/Program%20Files/Groovy/Groovy-1.7.0/lib/batik-svg-dom-1.7.jar
file:/C:/Program%20Files/Groovy/Groovy-1.7.0/lib/batik-svggen-1.7.jar
file:/C:/Program%20Files/Groovy/Groovy-1.7.0/lib/batik-swing-1.7.jar
file:/C:/Program%20Files/Groovy/Groovy-1.7.0/lib/batik-transcoder-1.7.jar
file:/C:/Program%20Files/Groovy/Groovy-1.7.0/lib/batik-util-1.7.jar
file:/C:/Program%20Files/Groovy/Groovy-1.7.0/lib/batik-xml-1.7.jar
file:/C:/Program%20Files/Groovy/Groovy-1.7.0/lib/bsf-2.4.0.jar
file:/C:/Program%20Files/Groovy/Groovy-1.7.0/lib/commons-cli-1.2.jar
file:/C:/Program%20Files/Groovy/Groovy-1.7.0/lib/commons-logging-1.1.1.jar
file:/C:/Program%20Files/Groovy/Groovy-1.7.0/lib/cssbuilder-0.3.jar
file:/C:/Program%20Files/Groovy/Groovy-1.7.0/lib/cssparser-0.9.5.jar
file:/C:/Program%20Files/Groovy/Groovy-1.7.0/lib/Filters.jar
file:/C:/Program%20Files/Groovy/Groovy-1.7.0/lib/flamingo-4.0.jar
file:/C:/Program%20Files/Groovy/Groovy-1.7.0/lib/flamingo-4.0dev.jar
file:/C:/Program%20Files/Groovy/Groovy-1.7.0/lib/flamingobuilder-0.2.jar
file:/C:/Program%20Files/Groovy/Groovy-1.7.0/lib/forms-1.2.1.jar
file:/C:/Program%20Files/Groovy/Groovy-1.7.0/lib/fxbuilder-0.2.jar
file:/C:/Program%20Files/Groovy/Groovy-1.7.0/lib/gant-1.9.0_groovy-1.7.0.jar
file:/C:/Program%20Files/Groovy/Groovy-1.7.0/lib/gfxbuilder-core-0.2.3.jar
file:/C:/Program%20Files/Groovy/Groovy-1.7.0/lib/gfxbuilder-svg-0.2.3.jar
file:/C:/Program%20Files/Groovy/Groovy-1.7.0/lib/gfxbuilder-swingx-0.2.3.jar
file:/C:/Program%20Files/Groovy/Groovy-1.7.0/lib/gpars-0.9.jar
file:/C:/Program%20Files/Groovy/Groovy-1.7.0/lib/groovy-1.7.0.jar
file:/C:/Program%20Files/Groovy/Groovy-1.7.0/lib/ivy-2.1.0.jar
file:/C:/Program%20Files/Groovy/Groovy-1.7.0/lib/jacob-1.14.3.jar
file:/C:/Program%20Files/Groovy/Groovy-1.7.0/lib/JFXtras-0.5.jar
file:/C:/Program%20Files/Groovy/Groovy-1.7.0/lib/jide-oss-2.6.2.jar
file:/C:/Program%20Files/Groovy/Groovy-1.7.0/lib/jidebuilder-2.2.jar
file:/C:/Program%20Files/Groovy/Groovy-1.7.0/lib/jline-0.9.94.jar
file:/C:/Program%20Files/Groovy/Groovy-1.7.0/lib/jsilhouette-geom-0.3.1.jar
file:/C:/Program%20Files/Groovy/Groovy-1.7.0/lib/jsp-api-2.0.jar
file:/C:/Program%20Files/Groovy/Groovy-1.7.0/lib/jsr166y-070108.jar
file:/C:/Program%20Files/Groovy/Groovy-1.7.0/lib/junit-4.7.jar
file:/C:/Program%20Files/Groovy/Groovy-1.7.0/lib/l2fprod-common-all.jar
file:/C:/Program%20Files/Groovy/Groovy-1.7.0/lib/macwidgets-0.9.4.jar
file:/C:/Program%20Files/Groovy/Groovy-1.7.0/lib/macwidgetsbuilder-0.2.jar
file:/C:/Program%20Files/Groovy/Groovy-1.7.0/lib/maven-ant-tasks-2.0.10.jar
file:/C:/Program%20Files/Groovy/Groovy-1.7.0/lib/miglayout-3.6.3-swing.jar
file:/C:/Program%20Files/Groovy/Groovy-1.7.0/lib/MultipleGradientPaint.jar
file:/C:/Program%20Files/Groovy/Groovy-1.7.0/lib/netty-3.1.5.GA.jar
file:/C:/Program%20Files/Groovy/Groovy-1.7.0/lib/sac-1.3.jar
file:/C:/Program%20Files/Groovy/Groovy-1.7.0/lib/scriptom-1.6.0.jar
file:/C:/Program%20Files/Groovy/Groovy-1.7.0/lib/scriptom-ie-6-tlb-1.6.0.jar
file:/C:/Program%20Files/Groovy/Groovy-1.7.0/lib/scriptom-office-2K3-tlb-1.6.0.jar
file:/C:/Program%20Files/Groovy/Groovy-1.7.0/lib/scriptom-sapi-tlb-1.6.0.jar
file:/C:/Program%20Files/Groovy/Groovy-1.7.0/lib/scriptom-scripting-tlb-1.6.0.jar
file:/C:/Program%20Files/Groovy/Groovy-1.7.0/lib/scriptom-wbem-tlb-1.6.0.jar
file:/C:/Program%20Files/Groovy/Groovy-1.7.0/lib/scriptom-wsh-tlb-1.6.0.jar
file:/C:/Program%20Files/Groovy/Groovy-1.7.0/lib/servlet-api-2.4.jar
file:/C:/Program%20Files/Groovy/Groovy-1.7.0/lib/spock-core-0.3.jar
file:/C:/Program%20Files/Groovy/Groovy-1.7.0/lib/svg-salamander-1.0.jar
file:/C:/Program%20Files/Groovy/Groovy-1.7.0/lib/swing-worker-1.1.jar
file:/C:/Program%20Files/Groovy/Groovy-1.7.0/lib/swingx-1.0.jar
file:/C:/Program%20Files/Groovy/Groovy-1.7.0/lib/swingx-beaninfo-0.9.5.jar
file:/C:/Program%20Files/Groovy/Groovy-1.7.0/lib/swingx-ws.jar
file:/C:/Program%20Files/Groovy/Groovy-1.7.0/lib/swingxbuilder-0.1.6.jar
file:/C:/Program%20Files/Groovy/Groovy-1.7.0/lib/swingxtrasbuilder-0.1.jar
file:/C:/Program%20Files/Groovy/Groovy-1.7.0/lib/timingframework-1.0.jar
file:/C:/Program%20Files/Groovy/Groovy-1.7.0/lib/trident-1.0.jar
file:/C:/Program%20Files/Groovy/Groovy-1.7.0/lib/tridentbuilder-0.1.jar
file:/C:/Program%20Files/Groovy/Groovy-1.7.0/lib/xml-apis-ext-1.3.04.jar
file:/C:/Program%20Files/Groovy/Groovy-1.7.0/lib/xstream-1.3.1.jar
file:/C:/Program%20Files/Groovy/Groovy-1.7.0/lib/xswingx-0.2.jar
file:/C:/Program%20Files/Java/jdk1.6.0_14/lib/tools.jar


The results returned from that simple Groovy script indicate what is already advertised about where Groovy automatically looks for classes and JARs: the current directory, the JRE extension mechanism directory, the Groovy installation's lib directory (%GROOVY_HOME%\lib or ${GROOVY_HOME}/lib), and the JDK's tools.jar. Had I specified any classes or JARs on the classpath using the -cp option, those would have been displayed here as well.

Tuesday, January 5, 2010

Groovy: Means, Medians, Modes, and Ranges Calculations

I needed to check a seventh grader's homework related to means, medians, modes, and ranges and Groovy seemed like a nice approach to writing a quick tool to check these calculations. The calculations used in this Groovy script are based on definitions of these terms in Mean, Median, Mode, and Range and in Mean, Median, and Mode: Overview.

I hurriedly put this script, modeMedianMean.groovy, together, so it could probably use some work. However, I wanted to check the homework with a quick and dirty tool and it does provide more examples of using some of Groovy's features and syntax.

modeMedianMean.groovy

#!/usr/bin/env groovy
// Script for calculating median, mean, mode, range, etc.
//
// http://www.purplemath.com/modules/meanmode.htm

if (args.length < 1)
{
println "You need to provide at least one numeric argument."
System.exit(-1)
}

// Place passed-in number arguments in List
values = new ArrayList<BigDecimal>()
for (i in args)
{
try
{
values.add(new BigDecimal(i))
}
catch (NumberFormatException numberFormatEx)
{
println "Ignoring non-numeric parameter: ${i}"
}
}
Collections.sort(values)

// Begin collecting metadata about the data
numberItems = values.size()
sum = 0
modeMap = new HashMap<BigDecimal, Integer>()
for (item in values)
{
sum += item
if (modeMap.get(item) == null)
{
modeMap.put(item, 1)
}
else
{
count = modeMap.get(item) + 1
modeMap.put(item, count)
}
}
mode = new ArrayList<Integer>()
modeCount = 0
modeMap.each()
{ key, value ->
if (value > modeCount) { mode.clear(); mode.add(key); modeCount = value}
else if (value == modeCount) { mode.add(key) }
};
mean = sum / numberItems
midNumber = (int)(numberItems/2)
median = numberItems %2 != 0 ? values[midNumber] : (values[midNumber] + values[midNumber-1])/2
minimum = Collections.min(values)
maximum = Collections.max(values)

println "You provided ${numberItems} numbers (${values}):"
println "\tMean: ${mean}"
println "\tMedian: ${median}"
println "\tMode: ${mode}"
println "\tMinimum: ${minimum}"
println "\tMaximum: ${maximum}"
println "\tRange: ${maximum - minimum}"


The next screen snapshot demonstrates this simple script in action with a variety of different numbers.



The examples demonstrated in the above screen snapshot demonstrated the sort and the basic functionality of median, mode, and mean, but all examples use integral numbers. The next screen snapshot includes some non-integer numbers and also shows the handling (ignored) of non-numeric parameters.



This simple script demonstrates how easy it is to use Groovy to accomplish repetitive tasks. With a little more time and effort, the script could be further improved, but it was sufficient for me to use to quickly check the seventh grade homework.

Monday, January 4, 2010

I Use Dead Programming Languages

In the late 1990s, a well respected and visionary colleague made the surprising statement, "Java is dead." That is probably the first time I had heard that phrase. Despite my respect for his considerable accomplishments, I thought that the statement was ridiculous. More than ten years later, it is still a pretty ridiculous statement. Java will "die" one day; all languages (and, even more so, all people) do. In that respect, Java "is dead," but so is every other programming language out there. I guess, then, it is safe to say that all programming languages are "dead."

When I enter the quotes-bound string "java is dead" into the Google search engine, I currently see 199,000 matches. Evidently, at least a few people have written this or written about someone else who has written this. Many of these posts make good points and the authors don't mean literally dead as of today, but the title "Java is dead" is obviously hyperbole. Who knew there could be so much Drama Queen behavior in software development?

The typical author of a "Java is dead" post is stating such claims because he or she doesn't like the Java feature set (such as the now-not-necessarily-the-case news that closures would not be in JDK 7; see Java Just Died (No Closures in Java 7)), he or she is concerned about the effectiveness and appropriateness of new features given backwards compatibility concerns (see Java: Evolutionary Dead End, Java is Dead?, and Java is Dead!), or he or she believes Java has become too complicated (see Java is Dead). Almost all of these posters have an alternative language in mind, though in almost all of these cases one could easily attack that alternative as well with some of the same criticisms. Indeed, Java is likely to outlive some of these languages.

For a "dead" language, Java isn't doing too badly. Java continues to top the Tiobe Programming Community Index, an almost boring feat at this point after holding this spot for roughly ten years (though it did swap places with second place C in the mid-2000s). Java continues to be a highly sought-after skill among potential new hires as proven by job searches at sites like Dice and Monster and obviously at JustJavaJobs.com. A Google search for "java -coffee -island" (without the quotes) reports 215 MILLION matches (and that's with the removal of pages/sites that might have happened to mention the Java programming language in conjunction with "coffee" or "island").

There are many reasons that the claim "Java is dead" will continue to be ridiculous (or at least overly dramatic) for at least several more years. First, many computer science programs and other training programs use Java as a primary teaching language. Second, there is a huge established code base that already uses Java. Third, there is significant vendor investment, tools, training, and other products that make both the vendors and their customers somewhat tied to Java. Fourth, Java boasts arguably the largest developer and open source ecosystem out there. When it comes to applications for which I want tools, vendors, and developers to be around with the right skills in the future, Java is still the leader. This point is well-made in Java: The Perpetually Undead Language.

Looking at other languages who have long since been pronounced dead shows us that Java's future may not be as bleak as some think. I heard (and hear) many enthusiastic Java developers talking about C++ being dead. I have noticed recently a resurgence in the interest in C++. The announcement of Google's Go programming language validates the interest there is in languages like C/C++.

One of the obstacles that faced Java from replacing C++ in places where Java obviously had advantages (such as GUI and database development) was the cost organizations faced to completely migrate C++ applications to Java applications. JNI, CORBA, web services, and similar technologies have made it possible to mix the two, but they all have their own complexities and issues. In a somewhat ironic twist, Java's greatest threat may be the rapidly rising popularity of alternative JVM-hosted languages such as Groovy, Scala, JRuby, and Clojure. Because these langauges run on the JVM, their integration with Java is much simpler than it ever was to integrate C++ and Java. This can potentially allow Java-heavy shops to more easily begin using these alternative JVM-hosted languages.

One development that could drastically impact the future of Java is Oracle's acquisition of Sun. However, for good or for bad, we won't know the depth or nature of that impact until the deal is finally approved (assuming that it is) and only time will tell. My best guess (and that's all it is) is that Oracle will do very little to change Java management in the near term.

If I was to base my opinions solely on what I observe in the blogosphere, I'd be sure that Java was already dead. It so happens, however, that reality is actually quite different than the blogosphere. When I talk to attendees at conferences, talk to other developers offline, and so forth, I get a much more realistic view of development. In that more realistic view, Java is far from dead.


Conclusion

Ted Neward wrote in mid-2008 that Java is Dead Like COBOL. In many ways, I still see this as the case. Java has warts and wrinkles. There are things I wish were done differently in Java. However, every language has its issues. When all things are considered (the large Java ecosystem of products, existing code, and investment), it is difficult to see what language one should tie himself or herself to for a good future that would be any more likely to succeed than Java. Instead, I prefer to continue to work with Java and to play with and work with other languages when they are more appropriate. I especially like the JVM-based languages because I can easily use them in conjunction with Java.

Java is far from dead and is probably further from language death than several of today's trendiest languages. Indeed, Java is only "dead" in the sense that all programming languages are destined to eventually die. I see some nice languages that complement Java (such as Scala and Groovy), but I don't realistically seeing them displacing Java altogether.

Saturday, January 2, 2010

RMOUG Training Days 2010 Presentations Blogs

Several people scheduled to present at Rocky Mountain Oracle Users Group Training Days 2010 have started blogging about their presentations. This post is a summary of some of these. The list of presentation summaries is available here.

Ken Lee has blogged about his presentation APEX Moves from the Garage to the Basement in his blog post RMOUG 2010 – February 17 – 18, 2010. Oracle Application Express (APEX) is an Oracle-provided tool for building web applications off of an Oracle database.

Kellyn Pedersen blogs about her upcoming presentation The Power of Parallel in her blog post Presenting at RMOUG 2010!!! This presentation appears to be related to Oracle parallel processing.

Chen Shapira is presenting What Every DBA Should Know About TCP/IP Networks and Analyzing Oracle Performance Using Time Series Models. She references the latter of these in two blog posts: Autocorrelation and Causation and Goodness of Data.

Jože Senegačnik is scheduled to present RMAN Tips and Services - Why Should One Use Them? One of the reasons that I'm a developer rather than a DBA is that the idea of backing up and restoring databases is one of the most boring that I can imagine. However, it is important and Oracle DBAs seem to love presentations related to Oracle Recovery Manager (RMAN).

Robert G Freeman mentions his 1/2 day university session in his blog post Creating VMWare and RAC on Windows, Part 2. He is also presenting on RMAN: Advanced RMAN Backup and Recovery.

I expect to see additional blogs from presenters at RMOUG Training Days 2010 as it approaches. Training Days will be held February 17-18 (and 1/2 day University Sessions on February 16) in the Colorado Convention Center in Denver, Colorado.