Welcome to TheGillis.net

Consider this site a collection of random notes about a variety of topics. I hope this information helps you in some way.

18 August 2004 - 5:58Java and Assert

I am a big fan of assertions in C++, and I always thought it would be great if Java had such a feature. I have known about the JUnit assertTrue() and assertFalse() statements, but they don’t act the same as the C++ equivalents. Exceptions are a decent option, but they have the drawback that non-RuntimeExceptions must be explicitly caught. Not only that but the logic to check simple things like pre and post conditions can be intrusive with if statements that usually take up at least three lines. Fortunately I have learned of a new feature to Java 1.4; the assert keyword. This shows where to learn the syntax as well as how to use them with javac, Apache Ant, and Eclipse.

Intro

I am happy to see that asserts made their way to Java. They are easy ways to quickly check for development conditions that can be safely ignored in a release system. When Java asserts are used, the runtime determines if it evaluates assert statements. The evaluation is off by default and can be enabled with a runtime flag.

Solution

The assert keyword is very easy to use, but you should be careful to avoid over using this feature because it can cause problems. The biggest problem is that they should not take the place of exceptions. This is especially true in public functions with user supplied values. In this case exceptions should be used since the problems that occur are “reasonable” to expect. You don’t know who’s passing information to you so you should not assume the caller is all knowing. A complete list of guidelines for when asserts should be used along with syntax and other things can be found here.

Problems

After you know that asserts exist, and you’ve learned how to use them correctly, you can still run into problems using them. I found that most default setups for compilers/IDE’s are not setup correctly to expect asserts. The most common error message that I’ve seen is:

Test.java:37: warning: as of release 1.4, assert is a keyword, and
           may not be used as an identifier
assert ASSERTIONS = true;

This warning and several strange errors occur. To figure out how to avoid these problems, read on.

JDK 1.4 Compiler

When compiling sources with the JDK 1.4 javac compiler, there is an extra compile flag needed “-source 1.4″. Without this the cryptic assert is a keyword error will occur. From what I understand this will make the resulting class file incompatible with classes compiled with JDK 1.3 or lower.

ECLIPSE

The Eclipse IDE will give you the same problems and it’s not entirely clear how to change the compiler flags. To get the equivalent:

  • Click Window->Preferences
  • Go to Java->Compiler->Compliance and Classfiles
  • Uncheck “Use default compliance settings”
  • Set “Generated .class files compatibility:” to 1.4
  • Set “Source compatibility:” to 1.4

Apache Ant

Ant can be used to compile sources with asserts by specifying the source parameter in the javac target. Here is an example javac target line using the correct source:

<javac srcdir="${src}" destdir="${build}" source="1.4">

Execution

Evaluation of assert statements are not on by default. To turn them on the “-ea” flag must be used. This is helpful in release environments since unneeded debug statements aren’t executed. If you don’t know if assertions are turned on or not inside a program, here is a quick tip I learned from O’Reilly’s Hardcore Java:

// Check for debug assertions
boolean ASSERTIONS = false;
assert ASSERTIONS = true;
String strVal = "Debug asserts are: " +
         (ASSERTIONS ? "On" : "Off");
System.out.println(strVal);

This will print if assertions are turned on or off and is found using the actual assert statement. I have found this works very well as a debug statement in the beginning of your main function as debug output.

Summary

I think that asserts were a great addition to the language, I just wish more people would use them. They are great for pre and post conditions on functions where you know will only be called by your code and will not be determined by user input. It shows you were errors are during testing, and during the release the overhead is very minimal. Hopefully I will run across it a little more often.

Links

No Comments | Tags: General

Add a Comment