Create your own
Lesson illustration

JDK, JRE, and JVM: Understanding Java’s Development and Runtime Components

Hello, and welcome to the first lesson in your Java foundations module. Over the next few lessons, you will move from Java’s execution model into writing, organizing, and debugging small Java programs—the foundation needed before Spring Boot can feel like more than framework magic.

This lesson resolves three acronyms you will encounter constantly in Java documentation and job discussions: JVM, JRE, and JDK. By the end, you should be able to explain what each one does, identify which one you need for a task, and describe what happens between writing a .java file and running an application.


The three layers: execution engine, runtime, development kit

The names are similar because the technologies are nested conceptually:

  1. The JVM executes Java bytecode.
  2. The JRE provides a complete environment for running Java applications, including the JVM and standard libraries.
  3. The JDK provides what you need to develop Java applications, including the runtime plus tools such as the compiler and debugger.
A nested-component diagram: the JRE contains the JVM plus Java libraries and runtime files, while the JDK includes the JRE and adds development tools such as `javac` and `java`.

A compact way to remember the distinction is:

TermFull namePrimary jobTypical contents
JVMJava Virtual MachineExecute compiled Java bytecodeClass loading, bytecode execution, memory management, garbage collection
JREJava Runtime EnvironmentRun an existing Java applicationJVM, Java standard library, runtime support
JDKJava Development KitBuild, test, debug, and run Java applicationsJRE-like runtime capabilities plus javac, debugging, packaging, and diagnostic tools

For your backend path, the practical answer is simple: install a JDK. An IDE such as IntelliJ IDEA uses its compiler and runtime tools, Maven will use it to build projects, and Spring Boot applications require it during development.


From Java source code to a running program

When you write Java, you create human-readable source code in files ending in .java.

public class HelloBackend {
    public static void main(String[] args) {
        System.out.println("Hello, backend!");
    }
}

The computer does not execute that source file directly. Java uses a two-stage model:

  1. The Java compiler, javac, reads HelloBackend.java.
  2. It checks the code for syntax and type errors, then produces HelloBackend.class.
  3. The .class file contains bytecode, an intermediate instruction format defined for the JVM.
  4. The java launcher starts a JVM.
  5. The JVM loads the bytecode, verifies it for safety, and executes it on the current machine.

The key boundary is this:

  • javac is a development tool supplied by the JDK.
  • The JVM runs the resulting .class bytecode.
  • The JRE supplies the JVM and the Java libraries the program relies on while running.

This is why a machine that only needs to run a prebuilt application does not conceptually need compiler tooling. But the developer creating that application does.

Here is a precise comparison to a model you may have encountered in C# and Unity:

Java ecosystemRough C#/.NET parallelImportant distinction
Java bytecode in .class filesIntermediate Language, or ILBoth are intermediate representations rather than direct CPU instructions
JVMCLR, Common Language RuntimeBoth execute managed code and handle services such as memory management
JDK.NET SDKBoth include build and development tooling
JRERuntime installationA runtime environment aimed at executing already-built applications

The analogy is useful, but do not assume all deployment and tooling details match exactly. In particular, Unity may use different runtime and compilation strategies depending on its target platform.


The JVM: the machine that runs bytecode

The Java Virtual Machine is not a physical computer. It is an abstract machine specification, with concrete implementations for Windows, macOS, Linux, and other platforms.

Its core responsibility is to load and execute compiled Java classes. In practice, a JVM also handles several essential runtime concerns:

  • Class loading: Finding and loading your application classes and library classes when they are needed.
  • Bytecode verification: Checking bytecode before execution to enforce important safety rules.
  • Memory management: Allocating memory for objects.
  • Garbage collection: Reclaiming memory for objects that are no longer reachable.
  • Execution optimization: Interpreting bytecode and, for frequently used code, compiling it into efficient native machine instructions at runtime.

You do not need to master those internals yet. The useful working model is:

The JVM makes compiled Java bytecode executable on a particular operating system and hardware platform.

Java source code and Java bytecode are designed to be portable. The JVM implementation is platform-specific. A JVM on Windows ultimately produces instructions appropriate for Windows and its hardware; a JVM on Linux does the equivalent job for Linux.

That is the basis of Java’s famous portability claim: you can distribute the same Java bytecode to different platforms provided that each platform has a compatible runtime. It does not mean every application is magically portable in every circumstance—native libraries, filesystem assumptions, environment variables, and external services can still make an application platform-dependent.

JVM, JRE, and JDK - Fully Explained in 5 Minutes

Watch “JVM, JRE, and JDK - Fully Explained in 5 Minutes” by Coding with John for a concise visual walkthrough of the nested relationship and the journey from source code to bytecode execution.

Watch from the JRE overview to see why standard-library classes are part of a runtime, then continue through the JVM role for bytecode loading, execution, and runtime services. Finish with the JDK explanation, focusing on why javac belongs to the development kit rather than the runtime.


The JRE: everything needed to run an application

The Java Runtime Environment is the execution environment for a Java application. At a conceptual level:

The JVM alone can execute bytecode, but most useful applications depend heavily on Java’s built-in APIs. Even our tiny example uses several library types:

  • System is a standard Java class.
  • String is a standard Java class.
  • System.out.println(...) uses output facilities provided by Java’s libraries.

Later, a Spring Boot application will use standard APIs for collections, dates and times, files, networking, concurrency, database access, and much more. These are not copied into every .class file you compile; they are made available by the runtime.

A useful distinction:

  • Your code is what your team writes.
  • Libraries are reusable code supplied by the Java platform or external dependencies.
  • The JVM executes your compiled code and the compiled library code.
  • The runtime environment makes those pieces available together.

A modern Java terminology note

Many tutorials, including older official documentation, describe the JRE as a separate install that users download solely to run Java programs. That model remains conceptually accurate, and it is still useful for understanding the roles.

However, in modern Java distributions, particularly from Java 11 onward, a separate, general-purpose standalone JRE download is less common. Developers normally install a JDK, and production systems often use either:

  • a JDK to run the application, or
  • a smaller custom runtime image containing only the runtime modules required by the application.

So in a modern backend job, treat JRE primarily as a role: the runtime capabilities required to execute Java software. Do not be surprised if you see only JDK downloads on a vendor’s website.

Java SE 8 Platform Overview

Read Oracle’s “Java SE 8 Platform Overview” for the official conceptual definitions of the JRE, JDK, and JVM. Although it refers to Java 8, the core role distinctions remain useful.

In the “JRE and JDK” section, read the JRE definition, then continue through the JDK paragraph ending with the JDK definition. Next, in “Java Virtual Machines,” read the JVM explanation. Focus on the distinction between portable bytecode and JVM implementations that are adapted to different operating systems.


The JDK: the toolkit a backend developer installs

The Java Development Kit is the complete developer-facing package. Conceptually:

Its best-known tools include:

ToolPurpose
javacCompiles .java source files into .class bytecode files
javaLaunches a Java application by starting a JVM
javadocGenerates API documentation from source-code comments
jarPackages compiled classes and resources into Java archive files
Debugging and diagnostic toolsHelp investigate behavior, performance, threads, and memory

Your IDE hides much of this. When you press Run, IntelliJ commonly compiles the project, chooses the right classpath, launches the JVM, and shows your application’s output. Those steps still happen; the IDE simply orchestrates them for you.

In backend work, higher-level tools build on the JDK rather than replacing it:

  • Maven will compile, test, and package your code using the JDK.
  • Spring Boot will run as a Java process inside a JVM.
  • Docker images for Java services include a Java runtime, even if the image does not contain all development tools.
  • A .jar file may package your application classes and dependencies, but it still needs a compatible Java runtime to execute.

This gives you a practical installation rule:

Writing, compiling, debugging, testing, or building Java: use a JDK.
Only executing a prebuilt Java application: use a runtime environment.

For the rest of this course, assume you are working with a current long-term-support JDK rather than a separate JRE installation.


A diagnostic checklist

When the terms blur together, ask what action is failing:

SituationLikely missing or relevant component
javac is “not recognized” or unavailableA JDK is absent or not configured on your system path
An application has compiled .class files but will not startThe Java runtime or launch configuration may be missing or incompatible
Code compiles on one machine and runs on several operating systemsThe shared artifact is bytecode; each system uses its own JVM implementation
A Java program cannot find List, String, or date/time classesThe runtime libraries or project configuration are incorrect
An IDE asks you to select a “Project SDK”It is asking which installed JDK should compile and run the project

Avoid saying “the JDK runs the code” when precision matters. A JDK contains the ability to run code, but the component performing execution is the JVM, supported by the broader runtime environment.


Key takeaways

  • A Java source file, such as OrderService.java, is compiled by javac into JVM bytecode, usually stored in a .class file.
  • The JVM loads and executes that bytecode. It also provides important runtime services such as class loading and garbage collection.
  • The JRE is the environment for running Java applications: JVM plus standard libraries and runtime support.
  • The JDK is the development kit: runtime capabilities plus tools for compiling, debugging, testing, and packaging.
  • Java bytecode is portable, while the JVM that executes it is implemented for a particular platform.
  • For Java and Spring Boot development, install and configure a modern JDK.

Next, you will make this model concrete by compiling and running a small Java application from both an IDE and the command line.

Can't find a good explanation? Sign up and we'll make it for you

Sign up