Java From the Command Line

In several of our courses we encourage students to develop programs with an IDE (Eclipse or Visual Studio) because IDEs have many built-in features that make it easier to work with large programs. Eclipse in particular provides good support for Java, so it is reasonable enough to use it to develop Java programs. But it is perfectly possible to write, compile, and run Java programs with any text editor and the command-line tools that come with typical Java implementations, and sometimes it can make sense to do so, or to use a combination of an IDE and command-line tools. This document describes how to do this on our Linux systems.

Situations in which you might find this useful include writing short throwaway programs, maklng very small changes to programs of any size, and running programs with command-line arguments or environment variables that should vary from execution to execution. You might even adopt a hybrid development strategy, developing the programs with an IDE and then running them from the command line (by opening a separate terminal window and navigating to the appropriate part of the IDE's workspace directory).

Writing Java programs

You can write Java programs with any text editor (program that lets you edit standard ASCII text files). Among UNIX enthusiasts, whose editor is better is a subject of perennial debate. I'm partial to vim, which many instructors show students a little about in our first course. If you tried it then and didn't like it, you might have a look at my hints and tips and give it another try; it really can be a good editor for working with program source code, once you get past the learning curve.

Compiling Java programs

Unlike C++ programs, but like Scala programs, Java programs don't compile to code that can be executed directly. Instead they compile to “byte code” (.class files) meant to be executed by a Java virtual machine (JVM).

The command javac invokes the Java compiler. For example, this command compiles

This assumes that all the classes needed by are either part of the standard Java libraries or in the current directory. If not, you can use the -classpath (short form -cp) to tell the compiler to find things. For example, here's the compile command again, but also looking in JAR file MyLib.jar:
javac -classpath .:MyLib.jar
(The . at the beginning of the class path says to include the current directory (.) in the path; entries in the path are separated by :.)

By default the .class files are created in the current directory, which can get messy if there are a lot of them. The -d option specifies a different location, e.g.

javac -d obj
to put them in directory obj.

If you want to compile many files, especially if they're contained in multiple directories, as is typically the case when using packages, you could type something such as the following, which finds all .java files in directories pkg1 and pkg2 and compiles them, placing the results in obj.

javac -d obj $(find pkg1 pkg2 -name "*.java")
(Shell script magic!)

Running Java programs

The command java runs the JVM. So for example, this command runs the main method in class Hello:

java Hello
To pass command-line arguments to main in Hello, type them at the end of the above command separated by spaces. Note that arguments that contain spaces or other characters that mean something to your shell (e.g., the wildcard character “*”) need to be enclosed in double or single quotes.

Again, the above command assumes that all the classes needed by are either part of the standard Java libraries or in the current directory. As with compiling, you can use the -classpath option to access classes in a JAR file or directory.

If the class whose main method you want to run is part of a package, you must specify the class's full name including package, as in this example:

java -classpath obj pkg.Hello
Note that this assumes that Hello.class is in obj/pkg, as described briefly in the next section.

Java packages versus directories/folders

Java normally expects source code for package x.y.z to be stored in a directory (folder) x/y/z. Note that Java, unlike Scala, is quite picky about adhering to this convention. Eclipse automatically creates an appropriate directory structure when you create a package; if you're working from the command line, you should do it yourself (e.g., with mkdir).