javac.exe : Java Glossary


Oracle’s free Java compiler that comes bundled with the JDK. If you install Java 1.8.0_131 in the default directory you should find it in J:\Program Files\java\jdk1.8.0_131\\bin\javac.exe.
Class and File Naming Rules Ant
CLASSPATH And File Naming Recipes Java Source Code Encoding
The Javac.exe Command Line java.exe
Programmatic Javac Invocation Learning More
What Gets Recompiled? Links
Circular References

Class and File Naming Rules

A class name must start with a capital letter. The source for that class must live in a plain text file with the same name (including case), with a *.java extension.

You cannot put more than one public class inside a *.java file.

Classes in the same package are accessible to each other, even if they are in different files. To access other classes, you must import them.

The source code must be stored in a directory with the same name as the package declared at the top of the file, including case, with the dots replaced by \ or / or whatever your platform uses for directory element separators.

Package names must be lower case, usually beginning com.yourwebsite to ensure global uniqueness.

It is a good idea to put every class in some package. Only experiments you plan to keep for under an hour should be without a package.

If you compile a class, then delete the *.class file and recompile, you will get the exact same *.class file, byte for byte. The time of compilation is not embedded in the file. Of course the new class file will get a new file date. Untouch can be used to put the dates of source and class file back to when they last actually changed.

CLASSPATH And File Naming Recipes

Here are my simplified rules for using CLASSPATH and naming the files on the javac.exe command line:
  1. Use Java version 1.1 or later, why not the latest? Configure your SET CLASSPATH= to clear it out. Avoid JDK (Java Development Kit) 1.0 if you can because its CLASSPATH is more complicated since you need to put the standard class jars on the classpath.
  2. In all that follows, everything is strictly case-sensitive.
  3. To
    CD \MyDir
    javac.exe -classpath .
  4. To compile a app in J:\com\mindprod\mypackage\, in package com.mindprod.mypackage, use
    CD \
    javac.exe -classpath . com\mindprod\mypackage\

The Javac.exe Command Line

Javac.exe Command Line Switches
Option Effect
-g generate all debugging information
-g:none remove all debugging information
-o optimise
-Xdepend Use a much slower more conservative approach to deciding which files need to be recompiled.
-XDignore.symbol.file Used when you want to use Oracle internal classes. Without it, you do not get access to all the classes in rt.jar just the ones mentioned in lib/ct.sym.
-nowarn suppress warning messages.
-verbose long version of error messages.
-classpath /mydir:/place/myCollection.jar overriding CLASSPATH environment variable, colon/semicolon separated. Infuriatingly, javac.exe won’t let you use the -cp shortcut.
-sourcepath /mydir:/place/myCollection.jar like CLASSPATH but describes with source *.java files are rather than *.class files, colon/semicolon separated.
-nowrite Don’t actually generate code, just check the syntax.
-deprecation warn of any use of any deprecated methods.
-d targetDir Place the output class files in this directory rather than the usual same directory as source.
-encoding UTF-8 what encoding was used to create the source files. Lets you embed fancy characters you would otherwise need to encode with \uxxxx.
-J runtimeflag  
@listOfFiles.txt To shorten or simplify the javac command, you may specify one or more files that themselves contain one filename per line. This enables you to overcome the command-line length limitation of Windows.
-source 1.3 What source code features you plan to use:
Javac.exe Source and Target Options
Version Options Notes
1.7 -source 1.7 -target 1.7
-XDignore.symbol.file=true lets you use Oracle proprietary classes in rt.jar
-Xlint:unchecked asks for warnings about when you should have used generics. -Xlint:fallthrough asks for warnings about cases without breaks. -Xlint:deprecation asks for detailed warnings about deprecated methods you used. -Xlint:-processing turns off annotation processing errors.
1.6 -source 1.6 -target 1.6
nothing major new added.
1.5 -source 1.5 -target 1.5
added generics, enumerations and annotations.
1.8 -source 1.8 -target 1.8 added lamba expressions
1.7 -source 1.7 -target 1.7 added switch with string cases
1.6 -source 1.6 -target 1.5 added annotations
1.5 -source 1.5 -target 1.4 added generics
1.4 -source 1.4 -target 1.4 added assertions and nio
1.3 -source 1.3 -target 1.3 added Swing
1.2 -source 1.3 -target 1.2 added ArrayList and other Collections. You must lie and code this as -source 1.3.
1.1 -source 1.3 -target 1.1 added a totally new event model, using Listeners. This is the level Microsoft has trapped many of its customers at. You must lie and code this as -source 1.3.
If your code does not use generics, for example, but does use assertions, you would set -source 1.4 to ensure you did not inadvertently use any generics, destroying the 1.4 compatibility. If you wanted to allow generics to be used, select -source 1.5. You will discover by experiment that Javac does not support all logical combinations of -source and -target. You just have to humour it.
-target 1.1 Specifies which the lowest number of JRE (Java Runtime Environment) you intend to run this code on. You can also specify -target 1.2 and 1.3.
-bootclasspath J:\j2sdk1.4.2_19\jre\lib\rt.jar The compiler is not smart enough to warn you if you use classes or methods not part of the targeted class library. You have to discover those errors by runtime tests. In Eclipse and other advanced IDEs (Integrated Development Environments) you can configure the Java version 1.5 compiler to use the Java version 1.4 library if you have that JRE also installed, which will catch these errors. If you use -target 1.4 and the 1.5 compiler you can force the compiler to use the 1.4 classfiles on the command line with
-bootclasspath J:\j2sdk1.4.2_19\jre\lib\rt.jar or -bootclasspath "J:\Program Files\Java\jdk1.8.0_131\jre\lib\rt.jar"
That way you can detect use of 1.5 classes that did not exist in 1.4, at compile time, e.g. StringBuilder. You might want to include more of the jars e.g. -bootclasspath J:\Program Files\java\jdk1.8.0_131\lib\; J:\Program Files\java\jdk1.8.0_131\jre\lib\ "J:\Program Files\Java\jdk1.8.0_131\jre\lib\ext\" However, I have not been able to get -bootclasspath listing directories, rather than individual jars to work. A brute force way to handle it is to install the Java version 1.6 JDK and compile with that. In JDK 1.3-, the colours had lower case names such as Color. white. Since these are static final constants, in Java version 1.4 or later, Sun gave them proper upper case names such as Color.WHITE. However, beware of using the upper case names it you want to target JDK 1.3- versions. Your programs will explode in a glory of exceptions from the missing support. The lower case names will work in any JDK version.
-version Verify you are using the version of javac.exe you think you are using.
-Xstdout Send error messages to stdout instead of stderr. This makes them easier to redirect to a file in Windows. For some idiotic reason this is no longer supported under Java version 1.3, (a result of intercorporate sniping at Microsoft?) It is supported with oldjavac.exe. Use tcc/TakeCommand to independently redirect stdout and stderr.
-Xdoclint Check for Javadoc problems
-Xdiags:verbose Get a longer version of the error messages
-help Get a list of options and what they do. Trust what it says over what I say here. Knowledge keeps no better than fish.
-X Get a list of the non-standard options. I have listed only the most common ones here.
Note there is no -cp or -jar option! Instead you must use -classpath for both functions.

Programmatic Javac Invocation

In Java version 1.5 - you have the deprecated, undocumented to fire up the Javac.exe compiler to run in the same JVM (Java Virtual Machine) and compile under your control. In Java version 1.6 or later you have the official JavaCompiler interface. JavaCompiler also allows you to compile on-the-fly generated code that lines only in RAM (Random Access Memory), never on hard disk.

What Gets Recompiled?

Any time you change the value of a static final constant, delete all the class files and recompile, aka clean compile. Otherwise classes that reference those static finals might not get recompiled and they will be stuck on the old value.
Before you release code, or do a major test, do a clean compile.
javac.exe will recompile all the *.java files you mention on the command line, whether they need it or not. Further, if your java source references *.class files not mentioned on the command line and they are missing, it will recompile them too. If the referenced class files are out of date, javac will recompile them, however, if other classes depend on the those freshly recompiled classes, they will not get automatically recompiled. That is why you should periodically delete all class and jar files in the universe and recompile everything especially before any release or global testing. This is known as a clean build. What I just said is not quite true. Javac.exe will look for *.class files on the classpath and if it can’t find them search the sourcepath (-sourcepath option) for the matching *.java files to recompile. By default, the sourcepath is the same as the classpath.

In ant, by default, the sourcepath is null in order to suppress recompiling classes outside the package being compiled. This avoids problems with recompiling with the wrong source or target JDK version. Further, ant only recompiles out of date files mentioned on the command line.

When you are testing, sometimes recompiling everything twice is needed to propagate the new versions to all corners, especially when you have jars or circular dependencies between packages i.e. A uses classes of B and B uses classes of A.

Here are cases where javac.exe fails to recompile.

  1. If you recompile A and A depends on B (which has not changed) and B depends on C (which has changed), javac will not recompile C, if you invoke it on A.
  2. If you change the value of a final static value in a class and recompile it, javac won’t necessarily recompile any other dependent classes which reference that field and have the old value burned into the class file as a literal.
  3. Classes in jars are never updated unless you explicitly update them with jar.exe.
Using a make utility to figure out what needs recompiling usually won’t do any better. It will take much longer since it will load javac.exe once per source file. You might as well recompile everything with javac.exe *.java. Invoking javac.exe once per source file or even once per directory will really slow you down. It is much better to invoke javac.exe once, and feed it everything either via the command line or the programmatic interface, (which is mainly what ant does for a living).

My rule of thumb is to erase all class files before a full application test or release. Also erase them if you suspect you are getting an old class file somewhere along the line. Most of the time, selective recompilation works fine. Usually you make changes to only one java file at a time before recompiling and none of the other files need it. Any time you change public static final constants is a good time to delete all the class files.

Periodically delete all class files. This cleans up class files from renamed and deleted source files. It gets rid of unused anonymous inner class files. Strange things can happen when you rename a module and fail to fix all the references and still leave the old class file lying about even if you delete the source.

Circular References

If class A references class B and class B references class A, you have a chicken and egg problem, technically called a circular reference. If you compile A first, the compiler won’t be able to find class B. If you compile class B first, it won’t be able to find class A. So what you do is compile them both at once in the same
javac.exe *.java
session and let it sort out the problem, or feed the problem to Ant to sort out.

ANT (A Neat Tool)

ANT compiles so much more quickly than using javac.exe on the command line, it really is the only way to fly if you have more than a few experimental student programs. A complete recompile of hundreds of projects is so quick, that I use it any time I have changed a public static final or a library used in more than one package.
Don’t spend too much time learning the intricacies of the javac.exe command line. It is primarily a student’s tool. As soon as you get serious and have an actual project, switch to ANT with genjar. Your compiles will be much faster. Your jars will automatically pull in needed classes from other packages. Your jars will not be stuffed with unused classes. Your scripts will work unmodified an any platform. Your build scripts will be easier to maintain. I would even go so far as to say, write a program to write your ant scripts, so they will all be completely consistent with your latest thinking.

Learning More

This page is posted
on the web at:

Optional Replicator mirror
on local hard disk J:

Canadian Mind Products
Please the feedback from other visitors, or your own feedback about the site.
Contact Roedy. Please feel free to link to this page without explicit permission.

Your face IP:[]
You are visitor number