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\jdk-9.0.4\bin for Java SE 9.0.4, for example.

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 & Modules).

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. On Windows, 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 might 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, NetBeans, and my own favorite IntelliJ IDEA. Of these three only NetBeans originated with Sun/Oracle and is currently transitioning to Apache. Eclipse and NetBeans are open source, and IntelliJ IDEA offers an open source edition that’s quite sufficient for Java development.

IDEs automatically manage the directory structure required by the Java compiler, and can produce output in executable JAR archives rather than individual class files. NetBeans does this by default while Eclipse and IntelliJ IDEA require some extra configuration. 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 did not support high DPI displays prior to Java SE 9. For older versions, most NetBeans fonts can be enlarged to a readable size via Tools: Options: Fonts & Colors. However, 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

Starting with Java SE 9, the JDK tool jshell provides a read-eval-print loop (REPL) to dynamically interpret Java code. There are also a number of third-party alternatives for older Java versions (please do a web search, I haven’t tried them). jshell is not directly comparable to PowerShell: it features neither a specialized shell language nor any extended functionality for system management. It’s quite handy for experimenting with Java language features and standard library APIs, though.

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 with some 6.0 features) 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 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

This site uses Akismet to reduce spam. Learn how your comment data is processed.