Senior 6 min · March 04, 2026

JDK vs JRE — javac Not Found in Production Builds

javac: command not found in production? JRE omits javac.

N
Naren · Founder
Plain-English first. Then code. Then the interview question.
About
 ● Production Incident 🔎 Debug Guide
Quick Answer
  • JDK = Tools + JRE — for developers writing Java code
  • JRE = JVM + standard libraries — for running Java programs
  • JVM = bytecode execution engine — platform-specific, language-agnostic
  • Install JDK if you compile code; install JRE-only (pre-Java9) if you only run apps
  • Compiling with a newer JDK than runtime JVM causes UnsupportedClassVersionError
  • Biggest mistake: thinking javac and java live in the same tool — javac comes only with JDK
Plain-English First

Think of writing a letter. The JVM is the postal system — it delivers your letter anywhere in the world without you worrying about roads or planes. The JRE is the envelope, stamp, and postal rules included — everything the postal system needs to do its job. The JDK is the complete stationery kit: the envelope, stamp, AND the pen, paper, and ruler you used to write the letter in the first place. You only need the stationery kit if you're writing letters. Everyone else just needs the postal system to receive them.

Every time you install Java, you're faced with a choice: do you download the JDK or the JRE? Most beginners just pick one at random and hope for the best. That guesswork trips you up the moment something breaks — like trying to compile code and getting a 'javac not found' error — because you installed the wrong thing. Understanding the difference isn't just academic trivia; it's the foundation for every Java project you'll ever set up.

Java was built around one revolutionary promise: write your code once, run it literally anywhere — Windows, Mac, Linux, a smart fridge. That promise only holds because of a clever three-layer architecture: the JVM handles the 'run anywhere' magic, the JRE bundles everything needed to support it at runtime, and the JDK gives developers all the tools to build Java programs in the first place. Each layer has a specific job, and they nest inside each other like Russian dolls.

By the end of this article you'll know exactly what each acronym means, how the three components relate to each other, which one to install for your use case, and you'll be able to explain the whole thing confidently in a job interview. No handwaving — we're going to trace a real Java file from source code all the way to running output, so you can see every layer doing its job.

The JVM — The Engine That Runs Your Java Code Anywhere

The Java Virtual Machine (JVM) is a program that runs on your computer and pretends to be a standardised, imaginary computer. Your Java code doesn't run directly on your CPU — it runs on this imaginary machine. That's the secret behind Java's 'write once, run anywhere' guarantee.

Here's why that matters. Windows, macOS, and Linux all have different CPUs and operating system rules. Normally, software compiled for Windows won't run on a Mac. Java sidesteps this by compiling your code into a neutral format called bytecode — instructions for the imaginary JVM machine, not for any real CPU. Every OS has its own version of the JVM, and each one knows how to translate that bytecode into whatever the local OS understands.

Think of bytecode as a universal recipe written in a language every chef (JVM) speaks, even though the actual kitchen equipment (CPU/OS) differs from country to country. The JVM is also responsible for memory management — it automatically cleans up objects your program no longer needs, through a process called garbage collection. You don't free memory manually in Java; the JVM handles it.

Critically, the JVM only understands bytecode. It cannot read your original .java source file. Something has to compile that source file first — and that's where the other two components come in.

HelloJVM.javaJAVA
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// This file is your SOURCE CODE — written by a human, readable by humans.
// The JVM cannot run this directly. It must be compiled to bytecode first.

public class HelloJVM {
    public static void main(String[] args) {

        // This message proves our code reached the JVM and executed.
        System.out.println("Hello from the JVM!");

        // The JVM knows which operating system it is running on.
        // We can ask it at runtime — notice we never wrote OS-specific code.
        String operatingSystem = System.getProperty("os.name");
        System.out.println("Running on: " + operatingSystem);

        // The JVM also tells us the Java version it is using.
        String javaVersion = System.getProperty("java.version");
        System.out.println("Java version: " + javaVersion);
    }
}
Output
Hello from the JVM!
Running on: Mac OS X
Java version: 17.0.9
Key Insight:
The JVM is the only component that actually RUNS code. The JDK and JRE exist to support it. When your program crashes with a NullPointerException or runs out of memory, it's the JVM throwing those errors — because it's the layer that's actually executing your instructions.
Production Insight
JVM startup is not instant — JIT compilation warms up over time.
Throughput can be 10x lower in the first few seconds after deployment.
Always measure warm-up latency, not just steady-state, for production SLAs.
Key Takeaway
The JVM is a platform-specific bytecode executor.
It makes 'write once, run anywhere' possible.
Without the JVM, Java doesn't run — full stop.

The JRE — The Complete Runtime Package Your Program Needs to Run

The Java Runtime Environment (JRE) is the JVM plus a large library of pre-written code that Java programs rely on at runtime. You can think of the JRE as the JVM bundled with its toolbox.

When your Java program says System.out.println(...), it's not magic — System, out, and println are all classes and methods written by the Java team, pre-compiled, and shipped as part of the JRE. This collection of pre-written classes is called the Java Class Library (or the Java API). It contains thousands of ready-made tools: ways to read files, connect to the internet, format dates, sort lists, and much more.

Without the JRE, the JVM would be like a car engine with no wheels, seats, or fuel system — technically impressive but not going anywhere.

Before Java 9, you could install the JRE standalone — perfect for end users who just wanted to run a Java app, not build one. From Java 9 onwards, Oracle merged the JRE into the JDK for distribution purposes. But the conceptual distinction still exists and still matters, especially when you're creating a minimal production deployment using the jlink tool, which lets you bundle only the JVM + the specific library modules your application actually uses, making your deployment tiny and fast.

JRELibraryDemo.javaJAVA
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
// This example uses classes from the Java Class Library — the part of the JRE
// that isn't the JVM itself. We didn't write ArrayList, LocalDate, or Collections.
// They came pre-packaged in the JRE. The JVM executes them just like our own code.

import java.util.ArrayList;    // From the JRE's java.util library
import java.util.Collections;  // Also from java.util
import java.time.LocalDate;    // From the JRE's java.time library (added in Java 8)

public class JRELibraryDemo {
    public static void main(String[] args) {

        // ArrayList is a resizable list — provided by the JRE, not written by us.
        ArrayList<String> programmingLanguages = new ArrayList<>();
        programmingLanguages.add("Java");
        programmingLanguages.add("Python");
        programmingLanguages.add("Rust");
        programmingLanguages.add("Go");

        // Collections.sort() is also a JRE utility — alphabetically sorts our list.
        Collections.sort(programmingLanguages);

        System.out.println("Sorted languages: " + programmingLanguages);

        // LocalDate.now() asks the JRE to fetch today's date using the OS clock.
        LocalDate today = LocalDate.now();
        System.out.println("Today's date from JRE: " + today);

        // We can also demonstrate the JRE's string formatting utilities.
        String message = String.format("There are %d languages in the list.", programmingLanguages.size());
        System.out.println(message);
    }
}
Output
Sorted languages: [Go, Java, Python, Rust]
Today's date from JRE: 2024-03-15
There are 4 languages in the list.
Pro Tip:
Every class you import that starts with java. or javax. is part of the Java Class Library shipped with the JRE. You're using the JRE's toolbox every single time you write import java.util.ArrayList — you just never had to download or install it separately because it came bundled with your JDK.
Production Insight
The JRE's class library is massive (over 4,500 classes in JDK 17).
In production, most apps use <10% of them — jlink strips the rest.
A custom runtime image can shrink a 200MB JRE to under 40MB.
Key Takeaway
JRE = JVM + standard libraries. Required to run any Java program.
Without the libraries, even System.out.println wouldn't compile.
Use jlink for minimal production runtimes.

The JDK — The Full Developer Toolkit That Contains Everything

The Java Development Kit (JDK) is the complete package. It contains the JRE (which contains the JVM), plus a set of developer tools you need to actually build Java programs. The most important tool is javac — the Java compiler. It's the program that reads your .java source file and outputs a .class bytecode file that the JVM can then execute.

Other tools bundled in the JDK include: javadoc (generates HTML documentation from your code comments), jar (packages your compiled classes into a single distributable archive file), jdb (a command-line debugger), jshell (an interactive console introduced in Java 9, great for experimenting), and jlink (packages a minimal JRE for your specific app).

The relationship is simple nesting: JDK ⊃ JRE ⊃ JVM. The JDK is the outermost layer. It contains everything. If you're writing Java code — which you are, since you're reading this — install the JDK. Full stop.

When you run javac HelloJVM.java in your terminal, you're using a JDK tool. When you then run java HelloJVM, you're using the JVM inside the JRE inside the JDK. Two different tools in the same box, each doing a distinct job in the pipeline from source code to running program.

CompilationPipelineDemo.javaJAVA
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
// STEP 1 — You write this source code and save it as CompilationPipelineDemo.java
// STEP 2 — You run:  javac CompilationPipelineDemo.java   (JDK tool: the compiler)
//           This produces: CompilationPipelineDemo.class  (bytecode — not human-readable)
// STEP 3 — You run:  java CompilationPipelineDemo         (JVM inside JRE inside JDK)
//           The JVM loads the .class file and executes the bytecode.

public class CompilationPipelineDemo {
    public static void main(String[] args) {

        // This line only runs because ALL THREE layers did their job:
        // JDK compiler turned our .java into .class bytecode.
        // JRE provided the System class and its out.println method.
        // JVM executed the bytecode instruction that calls println.
        System.out.println("All three layers (JDK, JRE, JVM) worked together to print this!");

        // We can prove the JDK compiled this by checking the class file version.
        // The number maps to a Java version: 61 = Java 17, 55 = Java 11, 52 = Java 8.
        int classMajorVersion = CompilationPipelineDemo.class.getPackage() == null
                ? 0 : 0; // Package check placeholder

        // A more reliable way — ask the JVM what version compiled this class.
        System.out.println("Class file compiled with Java spec version: "
                + System.getProperty("java.class.version"));

        System.out.println("JDK version used to compile: "
                + System.getProperty("java.version"));

        System.out.println("JVM vendor running this code: "
                + System.getProperty("java.vendor"));
    }
}
Output
All three layers (JDK, JRE, JVM) worked together to print this!
Class file compiled with Java spec version: 61.0
JDK version used to compile: 17.0.9
JVM vendor running this code: Eclipse Adoptium
Watch Out:
The JDK version you compile with sets a minimum bar. If you compile with JDK 17 and someone tries to run your .class file with a JVM from Java 8, they'll get an UnsupportedClassVersionError. Always know your target runtime version. Use javac --release 11 MyFile.java to compile for a specific older version.
Production Insight
Mixing JDK versions in CI/CD is a common source of 'works on my machine' bugs.
Always pin the JDK version in build scripts and Docker images.
A CI image that uses 'openjdk:11-jdk' might accidentally download 17 if tag is stale.
Key Takeaway
JDK = JRE + dev tools. Install if you compile code.
javac is a JDK-only tool — JRE won't have it.
Use --release flag to control target bytecode version.

How JDK, JRE, and JVM Work Together — Tracing One Java Program End to End

Let's tie it all together by following a single Java file through its complete lifecycle. This is the story you should be able to tell from memory.

You open your editor and write Greeting.java. At this point nothing has happened yet — it's just a text file. You run javac Greeting.java. The javac compiler (a JDK tool) reads your source code, checks it for syntax errors, and if everything's fine, produces Greeting.class. This .class file contains bytecode — compact, platform-neutral instructions that no human CPU understands natively, but every JVM does.

Now you run java Greeting. The java launcher (part of the JRE) starts the JVM and hands it your .class file. The JVM's class loader finds Greeting.class and loads it into memory. The JVM then runs a Just-In-Time (JIT) compiler that translates the bytecode into native machine code for your specific CPU — this happens at runtime, which is why Java 'warms up' over time and gets faster the longer it runs. Finally, your main method executes, the JRE's System.out.println does its job, and you see output in the terminal.

Three layers. One seamless pipeline. Understanding this flow means you can diagnose almost any Java setup problem on your own.

Greeting.javaJAVA
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
// Full end-to-end example — write this, compile it, run it, and trace every layer.
//
// COMPILE:  javac Greeting.java          <-- JDK's javac tool is used here
// RUN:      java Greeting                <-- JVM (inside JRE inside JDK) takes over here

public class Greeting {

    // The JVM always looks for a method with EXACTLY this signature as the entry point.
    // 'public' — callable from outside. 'static' — no object needed to call it.
    // 'void' — returns nothing. 'String[] args' — command-line arguments passed in.
    public static void main(String[] args) {

        String recipientName = "Java Developer";

        // System      — a class provided by the JRE's java.lang library (auto-imported)
        // .out        — a static field on System; it's a PrintStream object
        // .println()  — a method on PrintStream that writes a line to the console
        System.out.println("Hello, " + recipientName + "!");

        // Demonstrating that the JVM manages memory for us.
        // We create an object — the JVM's garbage collector will clean it up
        // automatically when this method ends and the reference goes out of scope.
        StringBuilder messageBuilder = new StringBuilder();
        messageBuilder.append("JDK compiled me. ");
        messageBuilder.append("JRE provided StringBuilder. ");
        messageBuilder.append("JVM is running me right now.");

        System.out.println(messageBuilder.toString());

        // When main() returns, the JVM will shut down cleanly.
        // No manual memory cleanup needed — that's garbage collection at work.
    }
}
Output
Hello, Java Developer!
JDK compiled me. JRE provided StringBuilder. JVM is running me right now.
Interview Gold:
When an interviewer asks 'what happens when you run a Java program?', walk them through this pipeline: .java source → javac (JDK) → .class bytecode → JVM class loader → JIT compiler → native machine code → execution. Most candidates say 'the JVM runs it' and stop. Going deeper shows real understanding.
Production Insight
JIT compilation can cause inconsistent latency during warm-up.
For latency-sensitive apps, trigger class loading before serving traffic.
Use -XX:+PrintCompilation to verify JIT activity in production.
Key Takeaway
The pipeline: .java → javac → .class → JVM → JIT → native.
All three layers work together every time you run a Java app.
Trace each step to diagnose runtime failures.

Choosing Between JDK and JRE: A Production Decision Guide

Now that you understand the layers, here's the practical decision framework for every environment:

  • Dev machines: Always install JDK. You need javac, jshell, jar, and other tools. The JDK includes the JRE, so you get everything.
  • Production servers running your app: Use a minimal JRE (or a custom runtime image built with jlink). This reduces attack surface and image size. Many teams use eclipse-temurin:17-jre-alpine as their base.
  • CI/CD build agents: JDK required for compilation. Make sure the version matches your target environment.
  • Containerization: Use multi-stage builds. Stage 1: JDK to compile. Stage 2: JRE to run. This slashes image size by 60-80%.
  • End users who just run a desktop app: Historically JRE, but nowadays you bundle a runtime with the app (using jlink or packaging tools like jpackage).

Java 9+ removed standalone JRE distributions from Oracle, but the concept persists. Vendors like Adoptium still offer JRE-only builds. Always read the distribution page carefully — if it says 'JDK' it includes everything; if it says 'JRE' you cannot compile.

There's one more nuance: when you run java from a JDK installation, you're using the JVM that lives inside the JRE that lives inside the JDK. But when you run javac, you're using a tool that only exists at the JDK level. This is why java -version succeeds on both JRE and JDK, but javac -version fails on JRE-only.

check_version.shBASH
1
2
3
4
5
6
7
8
9
10
11
12
13
14
#!/bin/bash
# Check if you have JDK or JRE by testing javac
echo "Checking Java environment..."
if command -v javac &> /dev/null
then
    echo "JDK detected: javac is available"
    javac -version
else
    echo "JRE detected: javac not found"
    echo "Install JDK if you need to compile code."
fi
echo ""
echo "Java version:"
java -version
Output
Checking Java environment...
JDK detected: javac is available
javac 17.0.9
Java version:
openjdk version "17.0.9" 2023-10-17 LTS
OpenJDK Runtime Environment Temurin-17.0.9+9 (build 17.0.9+9)
OpenJDK 64-Bit Server VM Temurin-17.0.9+9 (build 17.0.9+9, mixed mode, sharing)
JDK ⊃ JRE ⊃ JVM
  • JVM: the drill — platform-specific, runs bytecode.
  • JRE: drill + bits and bits — JVM + standard libraries.
  • JDK: drill + bits + screwdrivers & wrenches — JRE + javac, jar, javadoc, etc.
  • You don't need the whole workshop to use the drill once it's assembled.
  • jlink lets you create a custom toolbelt with only the bits your project uses.
Production Insight
A multi-stage Docker build with JDK compile + JRE runtime reduces final image from ~400MB to ~150MB.
For security scans, smaller images mean fewer CVEs to patch.
Custom jlink images can go under 40MB for simple microservices.
Key Takeaway
Dev machines: JDK. Production servers: JRE or custom jlink image.
Test compilation target before deployment.
Use --release flag religiously to avoid UnsupportedClassVersionError.
● Production incidentPOST-MORTEMseverity: high

The 'javac Not Found' Production Panic

Symptom
CI build fails with 'javac: command not found' on a fresh Ubuntu server. Docker image runs the app fine via 'java -jar', but compilation step errors out.
Assumption
They assumed 'java' and 'javac' come together because the local dev machine had both. The production Docker base image had only the JRE (via 'java:17-jre-alpine').
Root cause
The JRE doesn't include javac, jar, or any JDK development tools. The build stage relied on a JDK command in a JRE-only container.
Fix
Changed the Docker build stage to use a JDK base image (e.g., 'openjdk:17-jdk-slim') for compilation, and a separate slim JRE image for runtime — multi-stage build pattern.
Key lesson
  • Always distinguish build-time images (need JDK) from runtime images (JRE or JRE-slim).
  • Use multi-stage Docker builds: JDK for compilation, JRE for running.
  • Verify installed Java components with 'java -version' vs 'javac -version' on every environment.
Production debug guideSymptom → Action guide for the most common Java environment problems5 entries
Symptom · 01
'javac' command not found
Fix
Run 'java -version' — if Java is present, you likely have only the JRE. Install the JDK (e.g., 'apt install openjdk-17-jdk' on Ubuntu).
Symptom · 02
UnsupportedClassVersionError at runtime
Fix
Check the class file major version with 'javap -verbose ClassName | grep major'. Then match it to the JVM version: 61=Java17, 55=Java11. Recompile with '--release' flag or upgrade the runtime JVM.
Symptom · 03
Compiled code runs fine locally but fails on server
Fix
Compare 'java -version' and 'javac -version' on both machines. Most likely the server has an older JVM. Use 'javac --release X' where X is the server's Java version.
Symptom · 04
Multiple Java versions installed — which one is used?
Fix
Check PATH order: run 'which java' and 'which javac'. On Linux, use 'update-alternatives --config java'. On Windows, check system and user PATH environment variables.
Symptom · 05
JAR works with 'java -jar' but IDE cannot run the project
Fix
IDE uses its own configured JDK. Check IDE settings → Build Tools → JDK. The IDE may point to a JRE instead of a JDK. Ensure the IDE project SDK is a JDK installation.
★ JDK/JRE/JVM Quick Cheat SheetRun these commands to pinpoint environment issues fast.
Not sure if JDK or JRE is installed
Immediate action
Run 'javac -version' — if command not found, you have only JRE.
Commands
java -version
javac -version
Fix now
Install JDK from adoptium.net or package manager.
UnsupportedClassVersionError+
Immediate action
Check compiled class version with javap.
Commands
javap -verbose MyClass.class | grep 'major version'
java -version (note the version number)
Fix now
Recompile with 'javac --release <target_version>' or upgrade runtime JVM.
Which JDK is the system using?+
Immediate action
Find the java binary path.
Commands
which java
ls -la $(which java) (check symlinks)
Fix now
Set JAVA_HOME environment variable to the intended JDK directory.
JAVA_HOME not set or points to wrong location+
Immediate action
Check JAVA_HOME variable.
Commands
echo $JAVA_HOME
ls $JAVA_HOME/bin/java
Fix now
Set JAVA_HOME in shell profile: export JAVA_HOME=/path/to/jdk; export PATH=$JAVA_HOME/bin:$PATH
JDK vs JRE vs JVM: Complete Comparison
Feature / AspectJVMJREJDK
Full nameJava Virtual MachineJava Runtime EnvironmentJava Development Kit
Primary jobExecute bytecode on your specific OS/CPUProvide the runtime — JVM + standard librariesProvide everything for building Java programs
ContainsBytecode interpreter + JIT compiler + GCJVM + Java Class Library (java.util, java.io, etc.)JRE + javac + javadoc + jar + jdb + jshell + jlink
File it works with.class bytecode files only.class bytecode files + library .jar files.java source files (compiles them to .class)
Who needs itEveryone running JavaAnyone running a Java app (end users, servers)Developers writing Java code
Can compile .java files?NoNoYes — via the javac command
Can run .class files?Yes — that's its whole jobYes — via the java launcher commandYes — JRE is included inside the JDK
Installed standalone?Bundled inside JRE, not installed alonePre-Java 9 yes; post-Java 9 merged into JDKYes — single download covers all three
Platform-specific?Yes — different JVM per OS/CPUYes — ships with the OS-specific JVMYes — download the JDK for your specific OS
Typical size~50 MB (core JVM only)~100–200 MB (JVM + libraries)~200–400 MB (everything)
Example vendor buildsHotSpot, OpenJ9, GraalVM (JVM only mode)Adoptium JRE, Oracle JRE, Amazon Corretto JREAdoptium JDK, Oracle JDK, Amazon Corretto JDK, GraalVM JDK

Key takeaways

1
The JVM is the engine that executes Java bytecode
it's platform-specific (different JVM for Windows, Mac, Linux) so your bytecode doesn't have to be.
2
The JRE = JVM + the Java Class Library. It's everything needed to RUN a Java program. Every import java.* you write pulls from the library the JRE provides.
3
The JDK = JRE + developer tools (javac, jar, javadoc, jshell). If you're writing Java, install the JDK
it includes the JRE so you never need both.
4
The compilation pipeline is
.java source → javac (JDK tool) → .class bytecode → JVM loads and JIT-compiles → native CPU execution. Knowing this flow lets you diagnose virtually any Java environment problem.
5
Use javac --release <version> to control bytecode compatibility. Never assume the runtime JVM matches your build JDK.

Common mistakes to avoid

5 patterns
×

Installing only JRE and then trying to compile code

Symptom
Running javac HelloWorld.java gives 'javac' is not recognized (Windows) or command not found: javac (Mac/Linux).
Fix
Uninstall the JRE-only distribution and download the full JDK from adoptium.net or oracle.com. The JDK includes the JRE, so you never need both installed separately.
×

Compiling with a newer JDK than the JVM version on the target machine

Symptom
Code compiles fine locally but throws java.lang.UnsupportedClassVersionError: Unsupported major.minor version 61.0 when deployed to a server.
Fix
Compile with a target flag that matches the server's Java version. For example, if the server runs Java 11, compile with javac --release 11 MyApp.java. This tells the JDK to produce bytecode compatible with Java 11 even if your local JDK is version 17.
×

Confusing the JVM with the Java language itself

Symptom
This causes real confusion when you hear that Kotlin, Scala, and Groovy 'run on the JVM' — the misconception is that the JVM is Java-specific.
Fix
Understand that the JVM only cares about bytecode, not which language produced it. Kotlin's compiler produces the same .class bytecode format that Java's compiler produces. The JVM runs all of it without knowing or caring which language was used. Java the language and the JVM are separate things that happen to be developed together.
×

Not using multi-stage Docker builds — deploying with JDK in production

Symptom
Docker images are huge (400MB+), have unnecessary tools, and increase surface area for security vulnerabilities.
Fix
Use a multi-stage Dockerfile: first stage with JDK for compilation, second stage with a slim JRE image for runtime. Copy the compiled JAR from the first stage. This typically reduces image size by 60-75%.
×

Assuming `java` and `javac` are always at the same version

Symptom
Different versions of JDK and JRE are installed, and PATH points to one for java and another for javac, leading to inexplicable build or runtime errors.
Fix
Always install JDK as your only Java distribution. Set JAVA_HOME to the JDK root, and add $JAVA_HOME/bin to PATH. Verify both java -version and javac -version report the same version.
INTERVIEW PREP · PRACTICE MODE

Interview Questions on This Topic

Q01JUNIOR
Can you explain the relationship between the JDK, JRE, and JVM? Which on...
Q02JUNIOR
If a user just wants to run a Java application on their machine but has ...
Q03JUNIOR
What is bytecode, and why does its existence mean Java programs can run ...
Q04SENIOR
Explain the difference between the command `java` and `javac`. Which com...
Q05SENIOR
What is the `--release` flag in javac, and when would you use it in prod...
Q01 of 05JUNIOR

Can you explain the relationship between the JDK, JRE, and JVM? Which one contains which?

ANSWER
The JDK (Java Development Kit) contains the JRE (Java Runtime Environment), which contains the JVM (Java Virtual Machine). The JVM executes bytecode and is platform-specific. The JRE adds the standard Java class library. The JDK adds developer tools like javac, jar, javadoc, and jlink. Think of it as nesting: JDK ⊃ JRE ⊃ JVM. If you only need to run a Java application, you need at least the JRE. If you want to write and compile Java code, you need the JDK.
FAQ · 5 QUESTIONS

Frequently Asked Questions

01
Do I need to install both JDK and JRE?
02
What is bytecode in Java and why does it matter?
03
If Java 9+ merged the JRE into the JDK, is the JRE concept still relevant?
04
Can I run a Java program without installing anything?
05
What's the difference between OpenJDK and Oracle JDK?
🔥

That's Java Basics. Mark it forged?

6 min read · try the examples if you haven't

Previous
Introduction to Java
2 / 13 · Java Basics
Next
Java Program Structure