Compiling Java source code
1 Java’s Compiled Targets 🎯
When you compile Java source code (.java files), the Java compiler (javac) doesn’t create a native machine code executable. Instead, it generates a special intermediate format called bytecode. This bytecode is stored in class files (.class files). These class files are the most fundamental compiled target in Java. They are platform-independent and contain instructions for the Java Virtual Machine (JVM).
1.1 What are they and when are they used?
- Class Files (
.class): These are the basic building blocks of any Java program. A separate.classfile is created for each class in your source code. You’d use them in development to test and run individual components. For simple programs, you can run a single class file using the commandjava MyClass. - JAR Files (
.jar): A Java Archive is a package format used to aggregate multiple class files, along with associated metadata and resources (like images, configuration files, etc.), into a single file. You’d use a JAR file to distribute your application. Instead of sending a folder full of hundreds of.classfiles, you can just send one single.jarfile. This makes deployment and management much easier. - WAR Files (
.war): A Web Archive is a specialized JAR file designed for web applications. It bundles all the necessary components for a web app, including servlets, JSP pages, HTML files, and other resources. You would use a WAR file to deploy a web application to a Java web server like Apache Tomcat or Jetty. - EAR Files (
.ear): An Enterprise Archive is a package format used to bundle one or more WAR and JAR files into a single deployable unit. This is typically used for large-scale enterprise applications that run on an application server (like GlassFish or JBoss) and consist of multiple modules.
2 The Java Runtime 💻
The Java Runtime Environment (JRE) is the set of tools and libraries required to run a Java application. At its core is the Java Virtual Machine (JVM). The JVM is the engine that executes the Java bytecode contained in .class and .jar files.
- JVM (Java Virtual Machine): This is the magic behind Java’s “write once, run anywhere” philosophy. The JVM takes the platform-independent bytecode and translates it into native machine code that the underlying operating system can understand. This process is called Just-In-Time (JIT) compilation.
- Java APIs (Application Programming Interfaces): The JRE also includes a rich set of libraries that provide core functionalities like networking, file I/O, graphical user interfaces, and more. Your Java programs rely on these APIs to perform various tasks.
You need a JRE installed on a machine to run any Java program.
3 Creating a Java Executable 🚀
While Java’s compiled targets aren’t native executables, you can still create a file that behaves like one. This is typically done by packaging your application into a JAR file and making it runnable.
- Package your code into a JAR: You’ll use a build tool like Maven or Gradle to automatically compile your code, resolve dependencies, and create a single, executable JAR file.
- Add a
Main-Classentry to the manifest file: The manifest is a special file inside a JAR that contains metadata about the package. TheMain-Classentry tells the JVM which class contains thepublic static void main(String[] args)method to run when the JAR is executed. - Run the executable JAR: With the executable JAR created, you can run it from the command line using
java -jar YourApplication.jar. As long as a JRE is installed on the user’s machine, the JVM will read the manifest file, find theMain-Class, and start your application.
For a true native executable that doesn’t require a JRE to be pre-installed, you can use tools like GraalVM Native Image or jpackage. These tools compile your Java application and the necessary parts of the JRE into a single, platform-specific executable file. This is useful for distributing desktop applications to end-users who may not have Java installed.