Java:Tools:Javac

From Juneday education
Jump to: navigation, search

Description

This page contains a lecture on the javac tool (command).

javac is a compiler that reads Java source code and transforms that into Java byte code (which it stores in a binary file with the .class suffix).

Example use

Simple case of compiling one file

If you want to compile the file Hello.java in the package org.exampleproject

$ javac org/exampleproject/Hello.java

If you want to compile the file Hello.java in the package org.exampleproject and put the class files in a separate directory called bin:

$ javac -d bin org/exampleproject/Hello.java

Compiling a class which imports other classes

Sometimes you need to give javac a classpath.

Let's say we have this directory structure:

.
|-- bin
`-- src
    `-- org
        `-- exampleproject
            |-- domain
            |   `-- DomainOjbect.java
            |-- main
            |   `-- Hello.java
            `-- util
                `-- HelperClass.java

The packages are called

  • org.exampleproject.domain
  • org.exampleproject.main
  • org.exampleproject.util

If we want to remain in the . directory, above both src and bin, and compile Hello.java and get the class files in a structure under the bin directory, we'd do this:

javac -d bin src/org/exampleproject/main/Hello.java

The argument to javac is a flag for where to put the class file(s) -d bin and the most important argument src/org/exampleproject/main/Hello.java which is the text file we want to compile.

But, if Hello.java imports for instance org.exampleproject.util.HelperClass, how can javac find the corresponding source code file for that class?

Remember, we are standing in a directory above src. The compiler javac will look for the class org.exampleproject.util.HelperClass in the current directory, beginning with looking for the org directory. But the only directories here are src and bin!

So the compiler will complain about not finding the package org.exampleproject.util when we try to compile the file src/org/exampleproject/main/Hello.java (because the Hello class imports org.exampleproject.util.HelperClass).

At first, you might think this is strange. But think about it! How could the compiler find src/org/exampleproject/main/Hello.java? That was simple! We gave the compiler the full relative path to the source code file, from our current directory. It didn't matter that src is not part of the package name for the package of Hello. The compiler javac wants as argument the relative (or absolute) path to the file we want to compile.

So that it could find the Hello.java, wasn't so strange, since we gave the full path to the file (relative to our current directory). But the compiler discovered that the Hello class imported org.exampleproject.util.HelperClass. So the compiler must check if it needs to compile also that class. But the only clue as to where to find the source code file for HelperClass comes from the package name org.exampleproject.util. Now, the compiler knows that a package corresponds to a path. So it starts looking for the org directory. But our current directory only contains the directories src and bin. That's why it complains that it can't find the package!

So if we are in a directory which is not immediately above the top package directory (in our case org), and the class we're trying to compile imports classes from another package, we must help the compiler to find the top-level package directory (again, in our case src).

This can be accomplished using another flag to javac, namely the -cp (for "class path") flag:

$ javac -d bin -cp src src/org/exampleproject/main/Hello.java

Think about that command as meaning the following: Dear javac, put the class files under the bin/ directory (-d bin), and look for packages in the src/ directory (-cp src) when you compile the textfile with source code in src/org/exampleproject/main/Hello.java.

Note that when compiling a class in a package and directing the class files to e.g. bin/ then javac will create the directories corresponding to the packages of the compiled classes. So if we compile Hello.java which is a class which imports org.exampleproject.util.HelperClass, we'll get the following directory structure as a result (note the new directories under bin/):

.
|-- bin
|   `-- org
|       `-- exampleproject
|           |-- main
|           |   `-- Hello.class
|           `-- util
|               `-- HelperClass.class
`-- src
    `-- org
        `-- exampleproject
            |-- domain
            |   `-- DomainOjbect.java
            |-- main
            |   `-- Hello.java
            `-- util
                `-- HelperClass.java

The DomainObject.java source code wasn't compiled, since neither Hello, nor HelperClass imported it.

Slides and videos

  • Presentation: TODO
  • Source code: TODO
  • Video: TODO

Links

Other pages on this Wiki about Jar

Further reading