Compiling Java Code

This post is a quick introduction aimed at programmers experienced with C# or other languages who are new to Java. It is intended as a companion piece to my article Java for C# Programmers which focuses on language differences. See the “Further Reading” section at the top of that article for the official Oracle tutorials and documentation, as well as other literature.

Prerequisites — You need the Oracle Java SE Development Kit (JDK), available from the Oracle Technology Network, or an equivalent such as OpenJDK for Linux. For command-line compilation, you must also add the bin subdirectory of your JDK installation to your shell’s executable search path. On Windows, that would be C:\Program Files\Java\jdk1.8.0_121\bin for Java SE 8u121.

Command-Line Compilation

Very short Java programs contained in a single file are easily compiled from the command line. This is a great way to quickly experiment with some particular feature. The following code is a minimal “Hello World” application for Java:

public class HelloWorld {

    public static void main(String[] args) {
        System.out.println("Hello World");
    }
}

Use the following steps to compile and execute this program:

  1. Save the code to a file called HelloWorld.java. This must be its exact name because the Java compiler requires that each public class is stored in a .java file of the same name.
  2. Compile the file with the command javac HelloWorld.java. This will generate a compiled class file named HelloWorld.class in the same directory.
  3. Run the class file with the command java HelloWorld. Note the absence of any file extension – the Java runtime implicitly assumes .class.

This minimal example lacks a package (i.e. namespace) declaration at the top. This is not a recommended practice but convenient for single-file programs. If you did specify a package you would have to create a corresponding directory structure (see Packages).

JavaFX Version — A GUI equivalent is somewhat more complex. The following code is an almost minimal “Hello World” application for JavaFX, the new standard Java user interface framework:

import javafx.application.Application;
import javafx.geometry.*;
import javafx.scene.*;
import javafx.scene.layout.*;
import javafx.scene.text.*;
import javafx.stage.Stage;

public class HelloWorldFX extends Application {

    @Override
    public void start(Stage primaryStage) {
        final Text text = new Text("Hello World");
        text.setFont(Font.font(36));

        final StackPane root = new StackPane(text);
        root.setPadding(new Insets(12));

        primaryStage.setScene(new Scene(root));
        primaryStage.show();
    }

    public static void main(String[] args) {
        launch(args);
    }
}

Most of the added lines are part of the ceremony that large GUI frameworks unfortunately tend to require. Use the following steps to compile and execute this program:

  1. Save the code to a file called HelloWorldFX.java.
  2. Compile the file with the command javac HelloWorldFX.java.
  3. Run the class file with the command javaw HelloWorldFX.

These steps are almost exactly the same as above, except that javaw rather than java is used to run the compiled class file. javaw instructs the Java Virtual Machine (JVM) that a GUI application is being run, so no connection to the command-line shell is established and javaw immediately returns after starting the application, without waiting for it to close. (If you try running HelloWorldFX with java instead, Windows 10 will actually assume the JVM has crashed after you close the application window!)

Integrated Development Environments

Unlike the Microsoft ecosystem, Java has no dominant IDE such as Visual Studio that is used by virtually everyone. The three most popular choices are Eclipse, IntelliJ IDEA, and my own favorite NetBeans. Of these three only NetBeans originated with Sun/Oracle and is currently transitioning to Apache.

IDEs automatically manage the directory structure required by the Java compiler, and usually produce output in executable JAR archives rather than individual class files. When running such JAR files from the command line, specify java -jar MyApp.jar or javaw -jar MyFXApp.jar.

NetBeans — I can offer two tips for this IDE. First, unless you need some advanced server bundle you can select “OS Independent Zip” as your platform on the NetBeans Download page. NetBeans requires no installation whatsoever. Once you’ve extracted the ZIP archive into some arbitrary directory, simply run bin\netbeans64.exe on Windows. On other platforms the shell script bin/netbeans should have the same effect, although I haven’t tested that.

Second, NetBeans is based on the older AWT/Swing GUI framework that does not yet support high DPI displays. Most NetBeans fonts can be enlarged to a readable size via Tools: Options: Fonts & Colors, but you need to manually edit a configuration file to increase the size of the basic IDE font. Among many other tips, this procedure is described in an article by product manager Geertjan Wielenga:

  1. Find the file etc/netbeans.conf in your NetBeans installation directory and open it in a text editor.
  2. Find the line that starts with netbeans_default_options="--fontsize.
  3. Change the number after fontsize to whatever looks best. I use fontsize 24 on my Windows system running at 192 DPI (200%).

Build Systems — As with IDEs, Java has no single standard build system like MSBuild for the original .NET Framework. Apache Ant, the newer Apache Maven, and the somewhat esoteric Gradle are commonly used. NetBeans defaults to Ant but also ships with Maven and offers a Gradle plug-in. Consult the respective websites for documentation in case you wish to customize the build process.

Dynamic Scripting

For now, there is no official OpenJDK or Oracle tool to dynamically interpret Java code in a read-eval-print loop (REPL). However, a Java shell called jshell is scheduled for release with Java SE 9, and a number of third-party alternatives already exist (please do a web search, I haven’t tried them). jshell is not directly comparable to PowerShell: it’s the same language as the runtime (Java), not a new one, and it doesn’t feature any extended functionality for system management.

The picture is bleaker when it comes to dynamically adding functionality to an existing Java application. Java ships with a scripting framework but the only scripting engine supplied by default is Nashorn (User’s Guide) which runs JavaScript (ECMAScript 5.1) rather than Java. Certainly, Nashorn and Java code can interact with each other and there’s even a REPL shell for Nashorn called jjs – but at the end of the day you’ll still have to write JavaScript.

There is one standardized way to dynamically compile and load Java code, namely through the JavaCompiler API. This mechanism is unfortunately very complex. If you decide to use it you’ll want to do a web search for tutorials, such as Create dynamic applications with javax.tools by David J. Biesack.

One thought on “Compiling Java Code

Leave a Reply