Day 22

Java Programming Tools

by Michael Morrison


CONTENTS

Trying to perform any craft without the proper tools is a daunting task at best. Java programming is indeed a craft, and like woodworking or engraving, your level of programming success largely depends on your choice of tools as well as your skill in using the tools. You begin this bonus week by looking inside the standard Java programming tools included with the Java Developer's Kit (JDK). Today's lesson isn't just a cursory glance at the Java tools, however. You actually dig into the details of using the tools, including some hidden features and capabilities that seem to have been glossed over in much of the Java documentation. After learning the ins and outs of the standard JDK tools, you'll finish up the lesson by taking a look at some of the more popular Java visual development tools.

Today's lesson covers the following major topics:

By the end of today's lesson, you will be well acquainted with the standard JDK tools and how they work. This insight into the standard tools will allow you to use them more effectively in your own projects. Even if you decide to use one of the visual tools highlighted toward the end of the lesson, such as Symantec Café or Visual J++, you may still sometimes find the JDK tools invaluable in certain situations.

Overview of the Standard JDK Tools

The JDK provides a core set of tools necessary for developing programs in Java. Even though the JDK tools aren't particularly fancy in their implementation, they are guaranteed to work with the latest Java release because updated JDK tools are written in Java and are a part of each release. And although third-party add-ons and development environments promise to make Java development smoother and easier, the JDK provides all the essential tools and information necessary to write professional Java applets immediately and at no cost. Because the JDK is Sun's official development kit for Java, you can always count on it to provide the most extensive Java support.

Following is a complete list of the tools that are standard with the JDK:

You'll learn about each of these tools in detail in today's lesson. Before you get started, however, it's important to make sure you have the latest version of the JDK. As of this writing, the latest version of the JDK is version 1.02, which is included on the accompanying CD-ROM. This version will probably be around for a while, so you should be okay using it. Just to be sure, you can check Sun's Java Web site at http://www.javasoft.com to see what the latest version is. This Web site provides all the latest news and information regarding Java, including the latest release of the JDK. Keep in mind that Java is a new technology that is still in a state of rapid change. Be sure to keep an eye on the Java Web site for the latest information.

The Runtime Interpreter

The Java runtime interpreter is a standalone version of the Java interpreter built into Java-compatible Web browsers, such as Netscape Navigator 3.0 and Microsoft Internet Explorer 3.0. The runtime interpreter provides the support to run Java executable programs in the compiled bytecode class format. Since the interpreter doesn't directly provide any means to view graphical output, you are limited to using it to execute purely textual Java programs and applications that manage their own graphics. If you want to run graphical Java applets, you need to use either the Java applet viewer or a Java-compatible Web browser.

You can think of the runtime interpreter as exposing the bare essentials of the Java runtime system. Even though I use the term bare essentials, the interpreter actually lets you do quite a lot. Essentially, you can run any Java programs that don't rely on the Applet class. In fact, the statement earlier about not being able to run graphical programs isn't entirely true; you can run graphical Java applications, but you just can't run Java applets. The difference between a Java application and a Java applet is that an application is responsible for creating and maintaining its own window should it require the need for graphical output, whereas an applet relies on a Web browser to provide a window on which to display graphics. So the Java interpreter is capable of executing both textual Java programs and graphical Java applications, but not applets.

Usage

The runtime interpreter is a command-line tool for running Java programs and applications; Java applets require the graphics and display support of a Web browser.

New Term
A command-line tool is a tool that is executed at a command prompt, such as a DOS or UNIX shell prompt, with a specified list of arguments.

The syntax for using the Java runtime interpreter follows:

java Options Classname Arguments

The Classname argument specifies the name of the class you want to execute. If the class resides in a package, you must fully qualify the name. For example, if you want to run a class called SolveIt that is located in a package called Equations, you would execute it in the interpreter like this:

java Equations.SolveIt

When the Java interpreter executes a class, what it is really doing is executing the main method of the class. The interpreter exits when the main method and any threads created by it are finished executing. The main method accepts a list of arguments that can be used to control the program. Following is the definition of the main method as specified by the Java language:

class DoIt {
  public static void main(String argv[]) {
    // do something
  }
}

Notice that main has a single parameter, argv, which is an array of String objects. This brings us to the Arguments argument for the runtime interpreter, which specifies the arguments passed into the main method. Any arguments passed to the runtime interpreter via Arguments are accessible from the argv parameter in main. The following interpreter call passes two numeric arguments to the main method in the DoIt class:

java DoIt 8 24

Technical Note
The fact that the Java runtime interpreter actually executes the main method when running a class should give you an idea about one of the reasons why you can't run applets using the runtime interpreter. Give up? The answer is that applets don't even have a main method, so there is no way for the runtime interpreter to know how to begin executing an applet.

The OptionsArgument

The Options argument specifies options related to how the runtime interpreter executes the Java program. Following is a list of the most common runtime interpreter options:

-debug
-checksource or -cs
-classpath Path
-mx x
-ms x
-noasyncgc
-noverify
-prof
-ss x
-oss x
-t
-verbose or -v
-verbosegc
-verify
-verifyremote
-DPropertyName=NewValue

The -debug option starts the interpreter in debugging mode, which allows you to use the Java debugger (jdb) in conjunction with the interpreter. You'll learn more about using the Java debugger a little later in today's lesson.

The -checksource option causes the interpreter to compare the modification dates of the source code files and executable class files. If the source file is more recent, the class is automatically recompiled and the new bytecode executable is loaded.

The Java interpreter uses an environment variable, CLASSPATH, to determine where to look for user-defined classes. The CLASSPATH variable contains a semicolon-delimited list of system paths to user-defined Java classes. Actually, most of the Java tools use the CLASSPATH variable to know where to find user-defined classes. The -classpath option informs the runtime interpreter to override CLASSPATH with the path specified by Path.

The -mx x option allows you to modify the maximum size of the memory allocation pool, or garbage collection heap, used by the interpreter. By default, the pool has a maximum size of 16MB (-mx 16m). x specifies the new maximum size of the pool and is measured in bytes by default. You can also specify x in either kilobytes or megabytes by appending the letter k or m (respectively) onto the value. Also, x must be greater than 1000 bytes, meaning that the pool must have a maximum size of at least 1000 bytes.

The -ms x option is similar to the -mx option, except it allows you to modify the initial size of the memory allocation pool rather than the maximum size. By default, the size of the pool is initially set to 1MB (-ms 1m). x specifies the new initial pool size, and is measured in bytes by default. Similar to the -mx option, you can also specify x in either kilobytes or megabytes by appending the letter k or m (respectively) onto the value. Additionally, x must be greater than 1000 bytes.

The Java runtime system typically performs garbage collection automatically to make sure unneeded memory stays freed up. This takes place in an asynchronous thread that runs alongside other threads in the runtime system. The -noasyncgc option alters this behavior by turning off asynchronous garbage collection. The result is that no garbage collection takes place unless it is explicitly called on or the Java program runs out of memory.

Technical Note
You can force an explicit garbage collection by calling the gc method in the System class.

The -noverify option turns all code verification off, meaning that no bytecodes are processed by the bytecode verifier. Typically, the verifier verifies code loaded into the system using a class loader.

The runtime interpreter includes a built-in profiler, which is invoked using the -prof option. The profiler's job is to report on the amount of time spent in each section of code as a program is executing, which can often be used to find performance bottlenecks in the code. The built-in profiler writes the profile information to a file called java.prof, which is a text file. The profile information consists of how many times each method was called and the relative amount of time spent in the method during each call. The larger the latter number is, the more costly the method in terms of processor overhead. You can easily use this information as a guide to determine the code on which to focus your code optimization efforts.

Note
Since the runtime interpreter, and therefore the built-in profiler, can only be used with textual Java programs and standalone applications, you may be wondering how to profile Java applets. Fortunately, you can use the profiler in the runtime interpreter in conjunction with the Java applet viewer. You'll learn how to do this a little later today when you find out about the applet viewer.

Every thread in the Java runtime system is given two stacks: one for Java code and one for C/C++ code. The presence of two stacks reflects the native code support in Java. The -ss x option allows you to alter the maximum stack size used by C code in a thread. The default C stack size is 128KB (-ss 128k). The x parameter specifies the new maximum size in bytes of the C stack, which must be greater than 1000 bytes. You can also specify x in either kilobytes or megabytes by appending the letter k or m (respectively) onto the value. Keep in mind that this option applies to all threads created during program execution.

Similar to the -ss x option, the -oss option allows you to set the maximum stack size that can be used by the Java code in a thread. The default Java code stack size is 400KB (-oss 400k). The x parameter specifies the new maximum size in bytes of the Java stack, which must be greater than 1000 bytes.

The -t option prints a trace of the bytecode instructions executed. This option only works with the non-optimized version of the Java interpreter, java_g. (You'll learn about the non-optimized interpreter in a moment.) The -t option generates a great deal of information that can give you a lot of insight into what is happening within a program, provided you are good at following raw bytecodes!

The -verbose option causes the interpreter to print a message to standard output each time a Java class is loaded. Similarly, the -verbosegc option causes the interpreter to print a message each time a garbage collection is performed. A garbage collection is performed by the runtime system to clean up unneeded objects and to free memory.

The opposite of the -noverify option, the -verify option causes the interpreter to run the bytecode verifier on all code loaded into the runtime environment. The default function of the verifier is to only verify code loaded into the system using a class loader. This default behavior can also be explicitly specified using the -verifyremote option.

The -D option allows you to redefine system property values. PropertyName specifies the name of the system property you want to change, and NewValue specifies the new value you want to assign to it.

New Term
System properties are global system variables that reflect the state of the Java runtime system. For example, the version of the Java runtime system is stored in the java.version system property.

The Non-Optimized Interpreter

Some distributions of the Java Developer's Kit include an alternate Java interpreter called java_g. This is a non-optimized version of the Java interpreter that executes Java bytecodes in a manner more suitable for debugging. If this interpreter is in your JDK distribution, be sure to use it when you are executing code within the Java debugger.

The Compiler

The Java compiler (javac) is used to compile Java source code files into executable Java bytecode classes. In Java, source code files have the extension .java. As you've seen throughout this book, Java source code files are standard ASCII text files, much like the source code files for other popular programming languages like C++. It is the job of the Java compiler to process Java source code files and create executable Java bytecode classes from them. Executable bytecode class files have the extension .class and represent a Java class in its usable form.

Java class files are generated on a one-to-one basis with the classes defined in the source code. In other words, the Java compiler generates exactly one .class file for each class you create. Since it is technically possible to define more than one class in a single source file, it is therefore possible for the compiler to generate multiple class files from a single source file. When this happens, it means that the source file contains multiple class definitions.

You may have heard something about just-in-time compilers in relationship to Java. It's important not to get these compilers confused with the Java compiler and the role it plays. The Java compiler is responsible for turning Java source code into Java bytecodes that can be executed within the Java runtime system. The Java virtual machine, which is a component of the runtime system, is responsible for interpreting the bytecodes and making the appropriate system level calls to the native platform. It is at this point where platform independence is achieved by Java; the bytecodes are in a generic form that is only converted to a native form when processed by the virtual machine.

Just-in-time compilers remove the role of the runtime interpreter by converting Java bytecodes to native code on-the-fly before executing a Java program. In this way, just-in-time Java compilers work more like the back end of traditional language compilers in that they generate code for a native platform. Similarly, the Java compiler works more like the front end of a traditional compiler in that it parses Java source code and generates internally useful bytecode classes.

Note
Both Netscape Navigator 3.0 and Microsoft Internet Explorer 3.0 include just-in-time Java compilers.

Keep in mind that Java executables are still centered around the bytecode class format. Even with just-in-time compilers in the picture, all you must be concerned with as a developer is generating the appropriate bytecode classes using the Java compiler. If no just-in-time compiler is present on a user's system, the bytecode classes will be processed and executed by the runtime interpreter. On the other hand, if a just-in-time compiler happens to exist on the system, the bytecode classes will be converted to native code and then executed. Either way, the key to executing Java programs is the bytecode classes, which are created by the Java compiler.

Usage

The Java compiler is a command-line tool whose syntax follows:

javac Options Filename

The Filename argument specifies the name of the source code file you want to compile. The compiler will generate bytecode classes for all classes defined in this file. Likewise, the compiler will also generate bytecode classes for any dependent classes that haven't been compiled yet. In other words, if you are compiling class A, which is derived from class B, and class B has not yet been compiled, the compiler will notice the dependency and go ahead and compile both classes.

The OptionsArgument

The Options compiler argument specifies options related to how the compiler creates the executable Java classes. Following is a list of the compiler options:

-classpath Path
-d Dir
-g
-nowarn
-O
-verbose

The -classpath option tells the compiler to override the CLASSPATH environment variable with the path specified by Path. This causes the compiler to look for user-defined classes in the path specified by Path. Path is a colon-delimited list of directory paths taking the following form:

.;YourPath

An example of a specific usage of -classpath follows:

javac -classpath .;\dev\animate\classes;\dev\render\classes A.java

In this case, the compiler is using a user-defined class path to access any classes it needs while compiling the source code file A.java. The -classpath option is sometimes useful when you want to try compiling something without taking the trouble to modify the CLASSPATH environment variable.

The -d option determines the root directory where compiled classes are stored. This is important because many times classes are organized in a hierarchical directory structure. With the -d option, the directory structure will be created beneath the directory specified by Dir.

The -g compiler option causes the compiler to generate debugging tables for the Java classes. Debugging tables are used by the Java debugger and contain information such as local variables and line numbers. The default action of the compiler is to only generate line numbers.

New Term
A debugging table is a collection of information about a program that is used internally by a debugger. Debugging tables are built directly into executable classes during compilation.

Warning
If you are going to be using the Java debugger to debug the classes generated by the compiler, you must use the -g option. Additionally, for debugging make sure you don't use the -O option, which optimizes the code.

The -nowarn option turns off compiler warnings. Warnings are printed to standard output during compilation to inform you of potential problems with the source code. It is generally a good idea to keep warnings enabled because they often signal problem areas in your code. However, you may run into a situation where warnings are getting in the way, in which case the -nowarn option might be useful.

The -O option causes the compiler to optimize the compiled code. In this case, optimization simply means that static, final, and private methods are compiled inline. When a method is compiled inline, it means that the entire body of the method is included in place of each call to the method. This speeds up execution because it eliminates the method call overhead. Optimized classes are usually larger in size to accommodate the duplicate code. The -O optimization option also suppresses the default creation of line numbers by the compiler. Keep in mind that the -O option should not be used when you plan on debugging the compiled code using the Java debugger.

New Term
Method inlining is the process of replacing each call to a method with the actual method code. Inlining often increases the size of the resulting class file, but it can help improve performance.

The -verbose option has somewhat of an opposite effect as the -nowarn option-it prints out extra information about the compilation process. You can use -verbose to see exactly what source files are being compiled and what class files are being loaded.

The Non-Optimizing Compiler

Some distributions of the Java Developer's Kit include an alternate Java compiler called javac_g. This version of the Java compiler generates code without some of the internal optimizations performed by the standard javac compiler. If this compiler is in your JDK distribution, be sure to use it when you are compiling code for debugging. Otherwise, stick with the javac compiler for all release code.

The Applet Viewer

The typical method of executing a Java applet is from within a Web browser that has a Web page loaded containing the applet. This is the typical scenario in which most Web users come into contact with Java applets. As a Java developer, you have another option for running Java applets that doesn't involve the use of a Web browser. This option is the Java applet viewer, which serves as a minimal test bed for Java applets. At times you may not want to hassle with using a full-blown Web browser to test an applet, in which case the applet viewer is an ideal alternative.

Even though the applet viewer logically takes the place of a Web browser, it functions very differently from a Web browser. The applet viewer operates on HTML documents, but it only looks for embedded applet tags; it ignores any other HTML code in the document. Each time the applet viewer encounters an applet tag in an HTML document, it launches a separate applet viewer window containing the respective applet.

The only drawback to using the applet viewer is that it doesn't show you how an applet will run within the confines of a real Web setting. Since the applet viewer ignores all HTML codes except applet tags, it doesn't even attempt to display any other information contained in the HTML document. So once you've tested your applet using the applet viewer, be sure to also test it using a Web browser just to make sure it works in the context of a real Web page.

Usage

The Java applet viewer is a command-line tool, meaning that it is invoked from a command prompt. The syntax for the applet viewer follows:

appletviewer Options URL

The URL argument specifies a document URL containing an HTML page with an embedded Java applet. The applet viewer launches a separate window for each applet embedded in the HTML document. If the document doesn't contain any embedded applets, the applet viewer will simply exit. Figure 22.1 shows the applet viewer in action.

Figure 22.1 shows the Animator demo applet, which comes with the Java Developer's Kit, running in the applet viewer. You run the applet by changing to the directory containing the Animator bytecode class and embedded HTML file and then executing the following statement at the command prompt:

Figure 22.1 : The Animator applet running in the Java applet viewer.

appletviewer example1.html

example1.html is the HTML file containing the embedded Java applet. As you can see, there's nothing complicated about running Java applets using the applet viewer. The applet viewer is a useful and easy-to-use tool for testing Java applets in a simple environment.

The OptionsArgument

The Options argument to the applet viewer specifies how to run the Java applet. There is currently only one option supported by the applet viewer, -debug. The -debug option starts the applet viewer in the Java debugger, which allows you to debug applets. You'll learn more about using the Java debugger a little later in today's lesson.

Commands

The applet viewer has a drop-down menu called Applet containing a group of commands, as shown in Figure 22.2.

Figure 22.2 : The Java applet viewer with commands available in the drop-down menu.

The Restart command restarts the currently loaded applet, resulting in a call to the start method for the applet. The Restart command does not reload the applet, however. Similar to Restart, the Reload command reloads the applet and then starts it. Reload is often a better command to use to restart applets as it ensures that an applet is completely reinitialized.

The Clone command launches another instance of the applet viewer executing the same applet. This command is useful when you want to run multiple copies of an applet. For example, a multiuser network applet might support multiple instances that can communicate with each other. You could load one instance of the applet and then use the Clone command to start other instances.

The Tag command displays a window showing the HTML applet tag for the executing applet. The Applet HTML Tag window is shown in Figure 22.3.

Figure 22.3 : The Applet HTML Tag window displayed by the Tag command.

The Info command displays a window showing information about the executing applet, including general applet information and information relating to the parameters used by the applet. This information is returned by the getAppletInfo and getParameterInfo methods of the Applet class. The Applet Info window is shown in Figure 22.4.

Figure 22.4 : The Applet Info window displayed by the Info command.

The Edit command is disabled in the current release of the applet viewer. It will presumably be activated in a future release of the applet viewer, in which case it will probably provide a way to alter the applet parameters in the HTML document containing the applet tag.

The Properties command displays a window with access options relating to HTTP and firewall proxies and servers, along with network and class access options. The AppletViewer Properties window is shown in Figure 22.5.

Figure 22.5 : The Applet Viewer Properties window displayed by the Properties command.

Finally, the Close and Quit commands perform the same function, which is shutting down the applet viewer. It's not clear why there are two different commands for closing the applet viewer-it's presumably an oversight.

Profiling Java Applets

You learned a little earlier today about the profiler built into the Java runtime interpreter. You learned that you can't profile applets using the runtime interpreter alone because you can't even run applets using the interpreter. However, you can profile applets by running the interpreter's profiler in conjunction with the applet viewer. In this case, the applet viewer is launched from within the runtime interpreter, like this:

java -prof sun.applet.AppletViewer URL

URL specifies the name of the HTML file containing an applet tag (or tags). Notice that the applet viewer is referenced using its fully qualified class name, AppletViewer. When you finish running the applet, the interpreter writes a text file named java.prof to the current directory. This file contains profile information for the applet you just ran. Refer to the earlier discussion of the profiler in the section "The Runtime Interpreter" for information regarding the meaning of the contents of this file.

The Debugger

The Java debugger (jdb) is a command-line utility that enables you to debug Java programs. The Java debugger uses the Java Debugger API to provide debugging support within the Java runtime interpreter. Although the debugger is a command-line tool, it still provides a wide range of standard debugging features such as setting breakpoints and single-stepping through code.

New Term
A breakpoint is a line of code you specify that halts the execution of a program.

New Term
Single-stepping is the process of executing your code one line at a time (in single steps).

Before you can use jdb, you must compile your code so that it includes debugging information. The Java compiler switch for doing this is -g, which causes the compiler to generate debugging tables containing information about line numbers and variables.

Note
Some distributions of the JDK also include an alternative Java compiler called javac_g. If you have this compiler in your distribution (look in the java/bin directory), use it, because it compiles code without using some of the internal optimizations performed by the javac compiler.

Because debugging is a very broad subject, I've tried to keep this discussion focused on the Java debugger and the basics of how it is used. For a more hands-on look at Java debugging, you may want to check out Sun's online Java debugger tutorials, which are located on Sun's Java Web site at http://www.javasoft.com/products/JDK/debugging/.

Usage

The syntax for using the Java debugger follows:

jdb Options <Classname>

The Classname argument is optional and specifies the name of the class you want to execute. The fact that Classname is optional brings up an interesting point regarding the usage of the debugger: There are two different ways to go about using the debugger, depending on whether you are debugging an application or an applet. For applications, you simply execute jdb directly and provide the name of the main class in the Classname argument, as the previous syntax shows. If you are debugging an applet, however, you must execute the debugger within the applet viewer, like this:

appletviewer -debug URL

In this case, URL refers to a document URL containing an HTML page with the applet to be debugged. Instead of directly executing the class, the applet viewer launches the debugger and allows you to debug the applet. Technically, there are three ways to use the Java debugger. The third technique involves attaching the debugger to an application that is already running in the interpreter. You'll learn a little more about this debugging approach in the next section.

The OptionsArgument

The Options argument is used to specify different settings regarding how a debugging session is started. Following is a list of the debugging options:

-host Hostname
-password Password

The -host option is used to specify the name of the host machine where an existing Java interpreter is running. In this case, the debugger attaches itself to the interpreter so the currently executing application can be debugged. You specify the name of the host machine in the Hostname argument.

The -password option is also used when attaching the debugger to an existing interpreter session. When the interpreter is started with the -debug option, a password is displayed that must be used when initiating the debugging session. You specify this password to the debugger via the -password option and the Password argument.

Commands

When the debugger is up and running, you control it through commands that are entered at a command-line prompt. The debugger command-line prompt is a > prompt by default, similar to DOS or UNIX shell prompts. This prompt specifies that there is no default thread running. The thread that is currently executing in the debugger is displayed in the command prompt itself, so the > prompt signifies that no thread is currently being debugged. When you are debugging a thread, the command prompt changes to a thread name followed by the current position of the stack frame, which is enclosed in square brackets. An example of a thread prompt is main[1], which signifies that the main thread is running and you are at the topmost position (1) in the stack frame.

Following is a list of some of the most useful debugging commands:

help
locals
print Object
dump Object
methods Class
classes
stop in Classname.Methodname
stop at Classname.LineNumber
step
cont
clear <Classname.LineNumber>

Possibly the most important command in jdb is the help command, which prints out a listing of all the available commands and what they do. The next three commands are all related to printing information about objects. The locals command displays the current value of all the objects in the current scope (stack frame). The print and dump commands are both used on objects independent of the current scope. The print command is used to print both entire objects and individual member variables; you simply specify the name of the object or member variable in the Object argument. Similar to print, the dump command also prints objects or member variables, but it prints more detailed information such as an object's inheritance.

The methods command is used to list all the methods defined in the class specified by Class. The classes command lists all the classes that are currently loaded into memory. The list generated by the classes command is often pretty large since many different classes end up being loaded behind the scenes even in simple Java programs.

Now that you have an idea how to look at the values of different things in the debugger, let's move on to some commands that are a little more exciting. The stop in and stop at commands are used to set breakpoints in methods and at specific lines of source code, respectively. For example, to set a breakpoint in the mouseDown method of an applet called Groovy, you would type the following command at the debugger command line:

stop in Groovy.mouseDown

When you click the mouse button in the applet window, the debugger will halt the applet at the beginning of the mouseDown method. To begin single-stepping through the method, you use the step command. The debugger executes one line of code for each step command issued. When you find out the information you need and are ready to get things running at full speed again, you use the cont command, which continues the normal execution of the program. Likewise, you can clear any breakpoints you set with the clear command.

That sums up the basics of using the Java debugger. Like any powerful tool, you'll gain confidence with the debugger by simply tinkering with it. I suggest running the debugger on a simple program and getting acquainted with some of the commands before trying to take on a serious debugging project.

The Class File Disassembler

The Java class file disassembler (javap) is used to disassemble a class file, which means the executable class file is resolved into a list of public data, methods, or raw bytecode instructions. The disassembler's default output consists of the public data and methods for a class. The class file disassembler is useful in cases where you don't have the source code for a class but you'd like to know something about how it is implemented.

Usage

The syntax for the disassembler follows:

javap Options ClassNames

The ClassNames argument specifies the names of one or more classes to be disassembled.

The OptionsArgument

The Options argument specifies how the classes are to be disassembled. The disassembler supports the following options:

-c
-p
-h
-classpath Path
-verify
-version

The -c option tells the disassembler to output the actual bytecodes for each method. The
-p option tells the disassembler to also include private variables and methods in its output. Without this option, the disassembler only outputs the public member variables and methods. The -h option specifies that information be created that can be used in C header files. This is useful when you are attempting to interface C code to a Java class for which you don't have the source code.

The -classpath option informs the disassembler to override CLASSPATH with the path specified by Path when looking for the input class or classes. The -verify option tells the disassembler to run the verifier on the class and output debugging information. Finally, the -version option causes the disassembler to print its version number.

The Header and Stub File Generator

The Java header and stub file generator (javah) is used to generate C header and source files for implementing Java methods in C. The files generated can be used to access member variables of an object from C code. The header and stub file generator accomplishes this by generating a C structure whose layout matches that of the corresponding Java class.

Note
You learned how to use the javah header and stub file generator on Day 20, "Using Native Methods and Libraries." You can think of today's coverage as more of a reference for the javah tool itself since you learn about all the options supported by javah.

Usage

The syntax for using the header and stub file generator follows:

javah Options ClassName

The ClassName argument is the name of the class to generate C source files from.

The OptionsArgument

The Options argument specifies how the source files are to be generated. Following are the options supported by the stub file generator:

-o OutputFile
-d Dir
-td Dir
-stubs
-verbose
-classpath Path

The -o option is used to concatenate the resulting header and source files when multiple classes are being operated on. When used, the -o option results in the concatenated information being stored in the file specified by OutputFile.

The -d option determines the root directory where the generated header and source files are stored. Along with writing the header and source files, the header and stub file generator also writes its own temporary files. The -td option specifies the directory where these temporary files are stored. By default, temporary files are stored in the directory specified by the %TEMP% environment variable; the -td option overrides this directory with Dir.

The -stubs option is probably the most important option supported by the header and stub file generator. The -stubs option causes C declarations to be generated from the specified Java class or classes. Without the -stubs option, only header files are generated. When you use the -stubs option, the header and stub file generator creates both header and stub files, which are both typically required to incorporate native C code with Java.

The -verbose option causes the header and stub file generator to print a message to standard output regarding the status of files as they are being generated. Finally, the -classpath option informs the header and stub file generator to override CLASSPATH with the path specified by Path when looking for the input class.

The Documentation Generator

The Java documentation generator (javadoc) is a useful tool for generating programming documentation directly from Java source code. The documentation generator parses through Java source files and generates HTML pages based on the declarations and comments. Sun's online Java API documentation was created using the documentation generator, which attests to the practicality of this tool.

Usage

The syntax for using the documentation generator follows:

javadoc Options FileName

The FileName argument specifies either a package or a Java source code file. For source code files, the documentation generator creates HTML pages based on the special documentation comments (/** and */) used throughout the code. The documentation generator reformats and includes all public and protected declarations for classes, interfaces, methods, and variables. You can include special documentation tags within the documentation comments that allow you a little more power and flexibility over the resulting documentation. You'll learn about these tags in a moment.

The FileName parameter to the documentation generator can also refer to a package name, in which case documentation is created for all the classes contained in the package. This is an easy way to crank out documentation for a large set of classes with one easy command.

The OptionsArgument

The Options argument enables you to change the default behavior of javadoc. Following are the options supported by the documentation generator:

-d Dir
-classpath Path

The -d option specifies where the generated HTML documents are stored. The -classpath option informs the documentation generator to override CLASSPATH with the path specified by Path when looking for the Java source files.

Documentation Tags

The documentation generator supports special tags for adding extra information to the generated HTML documents. All the tags begin with an @ symbol and must appear at the beginning of a line. Following are the tags related to the generation of class documentation:

@see Classname
@see FullyQualifiedClassname
@see Classname.Methodname
@version Version
@author AuthorName

The @see tags all add a "see also" hyperlink to the HTML document that refers to a class or method within a class. This is an easy way to provide associations between classes in the documentation. Sun's Java API makes great use of the @see tag to provide cross-references between classes.

The @version tag allows you to include version information with the class, as specified by Version. Version can contain any text you choose relating to the version of the code. The @author tag lets you provide the name of the author or authors of the source code, as specified by AuthorName.

Following is an example of source code making use of the class documentation tags:

/**
 * A class for modeling precious gems.
 *
 * @see      Object
 * @see      gemology.Rock
 * @version  2.0  Dec 5, 1996
 * @author   Brett Weir
 */
class Gem extends Rock {
  // class definition
}

Notice that the class documentation comment and tags appear just before the class definition. This is important because the documentation generator associates this comment with the Gem class. You can also associate comments with variables and methods in a similar way. For variables, you are limited to using the @see tag. For methods, however, you can use a few other tags:

@param ParamName Description
@return Description
@exception Classname Description

The @param tag is used to add the method's parameters to the Parameters section generated in the HTML document. The Parameters section is an HTML section that lists the parameters required of a method. ParamName refers to the name of the parameter as defined by the method, and Description is a text description of the parameter.

The @return tag adds a Returns section to the HTML document that brings attention to the return value of the method. You simply provide a description of the return value in Description.

Finally, the @exception tag adds a Throws section to the HTML document, which lists the exceptions potentially thrown by the method. You specify the exception in Classname along with a description of what circumstances result in the exception being thrown in
Description. You can use multiple exception tags. The documentation generator automatically creates a hyperlink to the documentation for the exception class referenced.

Following is an example of source code that uses the method tags:

/**
 * Determines an estimate of the gem's value.
 *
 * @param      weight   The weight of the gem in carats.
 * @param      color    The color of the gem (0 -> 1.0).
 * @param      clarity  The clarity of the gem (0 -> 1.0).
 * @return     The estimated value of the gem.
 * @exception  NumberFormatException  When the color or clarity isn't
 *             in the range 0 -> 1.0.
*/
public int estimateValue(float weight, float color, float clarity) {
  // method definition
}

Visual Development Tools

Even though the JDK tools are powerful and certainly adequate for serious Java programming, few people will argue the benefits of using visual development tools. Along with providing feature-packed source code editors, most visual tools combine many of the standard Java programming tools within one environment. For example, from one development environment you can typically edit, compile, run, and debug Java programs. This seemingly simple merger of tools can really help save precious development time.

Although providing visual versions of the standard Java command-line tools is a benefit in and of itself, visual development tools rarely stop there. Most visual tools also include sophisticated project-management facilities as well as code-generation tools for creating applet templates with complete source code that performs a certain type of core functionality. Some visual tools even go a step further and eliminate much of the programming. These tools focus on harnessing prebuilt components that allow you to develop Java programs without actually writing Java code. These types of tools are typically a little more limited because of their high-level design, but they can save enormous amounts of time and energy in certain cases.

The rest of today's lesson focuses on some of the more popular Java visual development tools that are currently available. My intention isn't to rate the tools or persuade you to try one over another. My goal is simply to let you know what's out there so you can investigate what type of tool might suit your needs. Many of the tools have evaluation versions that you can download for free from an associated Web site, so you can very easily try them out for yourself and come to your own conclusions. Have fun!

Sun's Java WorkShop

Sun's Java WorkShop is a visual development tool written entirely in Java. This is an interesting tool because its design is very Web-centric, meaning that much of the tool itself is comprised of Java applets embedded in HTML pages. Java WorkShop is currently available for Windows and Solaris systems. You can check it out at http://www.sun.com/sunsoft/Developer-products/java/, which is Sun's Java WorkShop Web site (see Figure 22.6).

Figure 22.6 : Sun's Java WorkShop Web site.

Symantec Café

Symantec Café is a visual Java development environment based on Symantec's popular C++ development environment. It was one of the first visual Java tools available and currently supports both Windows and Macintosh platforms. You can get the latest information about Café at Symantec's Café Web site (see Figure 22.7), which is located at http://cafe.symantec.com/.

Figure 22.7 : The Symantec CafeWeb site.

Microsoft Visual J++

Microsoft finally decided to enter the Java development foray in full force with Visual J++, which is a visual Java tool similar to their popular Visual C++ development environment. Visual J++ currently is available only for the Windows platform. You can check out Visual J++ at Microsoft's Visual J++ Web site (see Figure 22.8), which is located at http://198.105.232.5/visualj/.

Figure 22.8 : The Microsoft Visual J++ Web site.

Natural Intelligence's Roaster

Natural Intelligence's Roaster is the first Java development environment targeted specifically for the Macintosh platform. For information about Roaster, check out Natural Intelligence's Roaster Web site (see Figure 22.9) at http://www.natural.com/pages/products/roaster/.

Figure 22.9 : Natural Intelligence's Roaster Web site.

Rogue Wave Software's JFactory

Rogue Wave Software's JFactory Java development tool is aimed more at rapid application development with a minimal amount of programming. This visual application generator is currently available for the Windows platform. You can get more information about JFactory from Rogue Wave Software's JFactory Web site (see Figure 22.10), which is located at http://www.roguewave.com/products/jfactory/jfactory.html.

Figure 22.10: Rogue Wave Software's JFactory Web site.

Penumbra Software's Mojo

Penumbra Software's Mojo development tool offers a programming environment based largely on reusable components. Granted, this is a trend common among many of the visual tools, but Mojo makes a big attempt to minimize custom coding whenever possible. Mojo is currently available for the Windows platform. You can check out Mojo at Penumbra Soft-ware's Web site (see Figure 22.11), which is located at http://www.penumbrasoftware.com/.

Figure 22.11: Penumbra Software's Mojo Web site.

Aimtech's Jamba

Aimtech's Jamba is one of the first offerings in the area of high-level visual Java tools. Jamba is aimed at Internet developers who want to harness the power of Java without any programming or scripting. Jamba is currently available for the Windows platform. You can get the scoop on Jamba by taking a stroll through Aimtech's Jamba Web site (see Figure 22.12), which is located at http://www.aimtech.com/prodjahome.html.

Figure 22.12: Animtech's Jamba Web site.

Kinetix's Hyperwire

The last of the visual tools is Kinetix's Hyperwire, which is another high-level tool somewhat similar to Jamba. Unlike Jamba, however, Hyperwire's emphasis is largely placed on creating highly graphical Java applets, including 3D graphics. Hyperwire is currently available for the Windows platform. You can get more information about Hyperwire from Kinetix's Hyperwire Web site (see Figure 22.13), which is located at http://www.ktx.com/products/hyperwire/.

Figure 22.13: Kinetix's Hyperwire Web site.

Note
High-level tools such as Jamba and Hyperwire are sometimes referred to as authoring tools because they involve little or no programming.

Summary

Even though Java is easier to use than some other programming languages, becoming a proficient Java programmer still presents a number of hurdles to most of us. One way to lower these hurdles a little is to become well acquainted with the development tools you are using. Possibly even more important is your initial choice of development tools, which can greatly affect your effectiveness as a Java programmer. Today's lesson addresses both of these concerns by presenting you with an in-depth look at the standard JDK tools, along with showing you some other options in the form of visual development tools.

Ultimately, your selection of a development tool or tools will depend on your level of expertise and your development style. Regardless of what type of tool you gravitate toward, be sure to take the time to learn all you can about it. If you are still unsure about what kind of development tool to use, stick with the JDK for a while, since it is guaranteed to meet the basic requirements necessary to build Java programs. Besides, understanding Java programming from the perspective of the standard JDK tools will ultimately give you more insight into the "big picture" of Java development.

You're probably tired of hearing me ramble on about tools by now. That's OK, because tomorrow you shift gears and head straight back into programming by learning about data structures in Java. I'm sure you can't wait!

Q&A

Q:
What is the significance of the profiler built into the runtime interpreter?
A:
The profiler is useful in assessing the relative execution times of different parts of a Java program, which is crucial in situations in which you are trying to improve the performance of a Java program. With the information generated by the profiler, you can target specific sections of code to focus optimization efforts.
Q:
How do I compile multiple classes within a single source code file? I keep getting compiler errors!
A:
Even though you can compile multiple classes that are defined in one source code file, only one of the classes can be public. Furthermore, the source file must be named after the class that is public. The purpose here is to allow you to include support classes in the same file with public classes. However, you are only allowed one public class per source code file.
Q:
When do I use the class file disassembler?
A:
The class file disassembler, although powerful in its own right, isn't necessarily a tool you will find yourself using a lot. Its primary purpose is dissecting Java classes for which you don't have the source code. Using the disassembler, you can look at all the public methods and member variables for a class, which can help a lot when you're trying to figure out how the class works. If you have a knack for details and a lot of Tylenol, you can also use the disassembler to look at the raw bytecodes for classes.
Q:
I still don't quite understand the distinction between development environments and authoring tools. What's the deal?
A:
Both of these types of tools qualify as visual tools, but there is a distinct difference between them. Development environments essentially replace the standard command-line JDK tools with integrated visual versions, while sometimes also adding some extra features like project management and simple code generation. Authoring tools, on the other hand, completely move away from the idea of writing source code by providing you with a means to build programs purely by assembling preexisting components. The main difference, then, is that development environments target Java programmers, while authoring tools are readily accessible to nonprogrammers as well.