Java Processes: jps
There are many times in Java development when it is important to know which Java processes are running. More specifically, I find myself needing the process ID of Java applications for running other tools against those processes or for terminating processes. There are several Sun JDK development tools, but one of my favorites is the jps tool (JVM Process Status Tool). This "experimental" tool lists the Java processes running on the target HotSpot JVM. As I previously blogged, my favorite use of this tool is
Java Application Launcher
The environment a Java application runs in can be significantly tweaked via the use of JVM arguments. In addition, JVM arguments allow for different levels of monitoring and analysis of the executing Java application. The command
java -helplists the standard options (standard across different JVM implementations) for the Java application launcher. The command
java -Xcan be used to see the Java application launcher's non-standard (X for extension specific to that JVM) arguments. In the HotSpot JVM, some frequently used extension arguments are
-Xmxfor initial Java heap size and maximum Java heap size respectively.
-Xbootclasspathoption can be used to either prepend (
/p) or append (
/a) resources to the bootstrap classpath.
If you wish to detect which JVM arguments your currently running Java application is using, you can use the ManagementFactory.getRuntimeMXBean().getInputArguments() call as described in Accessing JVM Arguments from Java. This technique takes advantage of Platform MXBeans available since J2SE 5 (custom MXBeans support was added in Java SE 6).
Two useful sources of information on the JVM parameters available when using Sun's JVM are A Collection of JVM Options and Charles Nutter's Favorite Hotspot JVM Flags. Both of these resources list and describe some/all of the not-recommended-for-the-casual-developer double X arguments (
-XX) that are available.
The javac Java compiler also has command-line arguments that can be of great use. Like the java application launcher, the javac compiler that comes with the Sun Java SDK includes both standard options and non-standard/extension options. These options are displayed in a manner consistent with that used for the application launcher. Non-standard options include bootstrap classpath append and prepend options, setting of endorsed standards path, setting of directory of installed extensions, and enabling and disabling of specific warnings (
-Xlintoptions including -Xlint:path).
The warnings reported by the Java compiler can be very useful in identifying things that either may be larger current problems than one realizes or could easily turn into more significant problems. Sun's javac compiler allows one to take relatively granular control of which warnings are enabled and disabled using
-Xlint(all warnings are reported when this is used by itself). Specific warnings can be reported by providing the type of warning after the
-Xlint:notation. If no reports of warnings are desired (other than those the Java Language Specification requires), the notation
One can use the
@SuppressWarningsannotation introduced with J2SE 5 to mark in code the warnings that should not be reported when the code is compiled. However, a natural question is which specific warnings can be suppressed in-code using this annotation. It turns out that this is compiler-specific. For Sun's compiler, the available warnings that can be suppressed with
@SuppressWarningsare listed here and here.
Java Classpath Issues
The Java classpath can be one of the most confusing things for a new Java developer. The classpath can become a complicated mess even for experienced developers when different issues arise due to different classloader behaviors, the presence of slightly different versions of libraries on the classpath, and incorrectly typed classpaths. Fortunately, there are several tools to help understand and better work with the classpath.
For those just learning Java and Java classpaths, a good starting point is to read Elliotte Rusty Harold's articles Managing the Java Classpath (Windows) and Managing the Java Classpath (Unix). These articles provide a good overview of the options one has for setting a classpath, why dynamically setting the classpath is preferred over using an environment variable, and provides the basics of how classpaths work with Java packages.
Because the Sun Java compiler will ignore an entry on the classpath that it cannot resolve, it is easy to think that one has correctly typed in a classpath entry even if it is incorrectly typed. The -Xlint:path extension option instructs the Java compiler to report any classpath entries that cannot be resolved.
The JARs, .class files, and other resources specified on a command-line classpath using
-cpare typically not the only resources on an application's classpath. Other sources of classpath information that must be considered include the standard Java classpath (for standard Java classes),
jre/lib/endorsed(uses bootstrap classpath). In addition classpaths may be different when using an IDE and are different when using web servers and application servers (classpath is typically determined by the contents of the WAR file and EAR file in those cases).
ClassNotFoundException Versus NoClassDefFoundError
One thing that can be a little tricky when first learning Java is distinguishing between the ClassNotFoundException and the NoClassDefFoundError. The Javadoc API documentation for each of these explains their use and why they might occur. In most cases, the easy way to differentiate between the two is that the
ClassNotFoundExceptionindicates that a class needed for compilation cannot be found on the classpath and a
NoClassDefFoundErrorindicates that the matching class that was found at compile time cannot be found at runtime. This differentiation between compile time and run time can be useful in figuring out when the classpath entry is missing.
It is also interesting to note that while
ClassNotFoundExceptionis a checked exception extending Exception directly,
NoClassDefFoundErroris actually an Error rather than an Exception. Note that
ClassNotFoundExceptioncan actually be encountered during runtime in a variety of situations such as the runtime on-the-fly compilation of JavaServer Pages, reflection, and, as the API states, "when an application tries to load in a class through its string name." Generally speaking, the causes of
NoClassDefFoundErrorare more diverse and difficult to resolve than those of
Some interesting and in-depth articles on class loading are available in the Demystifying Class Loading Problems series. Other references regarding the difference between these two exceptions are available at Difference Between ClassNotFoundException and NoClassDefFoundError, What is the Difference Between ClassNotFoundException and NoClassDefFoundError?, Java Fanatics: NoClassDefFoundError versus ClassNotFoundException, and ClassNotFoundException and NoClassDefFoundError.
UPDATE (2 March 2009): Identifying an Instance's Original Classpath Definition
UPDATE (2 March 2009): This subheading and entire paragraph have been added since the original post. Some of the
NoClassDefFoundErrors one might run into can be traced to multiple definitions of the same class on the classpath with slight differences. One way to see which class definition a loaded class is using is described in another blog post of mine.
Java provides some standard properties that can be used for several different benefits. An often used property from this set include
line.separatorfor a platform-independent reference to a new line. It is not easy to remember all of the available system properties, especially those that are not used often. Fortunately, several resources either list these or provide code examples of how to see a list of them. For example, Java Standard System Properties lists them, How to Print All the Java System Properties demonstrates how to programmatically list them, and Java: System Properties both demonstrates how to get the properties via code and lists them. The Javadoc-based API documentation for System.getProperties() lists the system properties that are always available. I've even been known to blog on properties before.
The Platform MXBean RuntimeMXBean provides a RuntimeMXBean.getSystemProperties() method that can be used to see the system properties as well.
View Swing GUI's Hierarchy with CTRL-SHIFT-F1
A nifty trick with Swing-based applications is the ability to use CTRL-SHIFT-F1 to see the Swing GUI's hierarchy. This is further demonstrated and explained in the Tech Tip Ctrl-Shift-F1 in Swing Applications.
The command-line serialver tool is useful for generating servialVersionUID attributes on classes that implement the Serializable interface. I have blogged previously on the serialver tool.
jar Tool and JAR Files
With the prevalence of IDEs and Ant and Maven for building Java code, it is easy to forget about the jar command. However, knowledge of the jar command can be useful for writing and running simple tests and examples. One of jar's characteristics that makes it most useful is the fact that it uses the ZIP compression format and uses similar syntax to the tar command. The versatile jar command can even be used to display the contents of an Adobe AIR
Executable JAR Files
JAR files can be made executable so that they can be run with a command line
java -jar someJar.jarwithout the need to specify classpath information or the main executable class in the JAR. The classpath and the main class to execute do not need to be explicitly stated because they are embedded in the executable JAR's manifest file with the Class-Path and Main-Class name/value pairs respectively. There are a few details to be aware of when using executable JARs (such as specifying the class path entries via directories relative to the location of the executable JAR file) and these details are covered in the blog posting Executable Jar File in Java.
JAR Manifest File Information
You can place essentially any name/value pair in a manifest file on its own line. While virtually any names and values can be used, there are some standard and accepted manifest name/value pairs one might wish to use. These include Class-Path, Main-Class, package version information (
Specification-Vendor, and implementation equivalents). The Manifest file is also used to seal packages in JAR files. See also the Wikipedia entry on Manifest File for more details.
JVM JMX Instrumentation
The JVM itself has been instrumented with Java Management Extensions (JMX) support since J2SE 5. This provides valuable information regarding the JVM and applications running in the JVM. Sun provides JConsole (since J2SE 5) and VisualVM (since Java SE 6 Update 7) with their SDK for easy developer monitoring of the JVM and its deployed applications.
Platform MXBeans have been provided with the Sun JVM since J2SE 5 and provide a wide variety of details regarding the JVM. Platform MXBeans provide information on JVM topics such as thread contention, operating system details, memory analysis, and logging management. As described earlier, the RuntimeMXBean provides interesting information such as the classpath in effect, the boot classpath, system properties, and JVM vendor and specification details. The available Platform MXBeans are described in greater detail in Using the Platform MBean Server and Platform MXBeans.
Java EE application servers also provide information via JMX.
UPDATE (18 February 2009) Generating a Stack Trace
UPDATE (18 February 2009) Eyal Lupu reminded me (see feedback) of a very handy tool during debugging (especially when processes are hanging). Forced generation of a stack trace with a SIGQUIT, CTRL+\, or CTRL-BREAK (Windows) is described in greater detail in An Introduction to Java Stack Traces.
Some of the Java documentation resources that I use most often include the overall JDK 6 Documentation (includes links to many of the other documents referenced in this blog posting), the Java SE 6 API documentation, the Java EE 5 API documentation, and specialized documentation such as the Spring Reference Manual and the Oracle Technology Network JPA Annotations Reference. Perhaps my favorite tool for finding useful documentation is the Google search engine.