ArchitectMind
  1. Home
  2. Tutorials
  3. Book 1 · Core Java & Modern Java
  4. Volume I
  5. Java Platform
Book 1 · Volume I — Java Language Fundamentals & Object-Oriented Programming · Topic 1.1

Java Platform

Java language, Java platform, JDK, JRE, JVM, Java SE, Jakarta EE and the Java ecosystem

17 min readStage 1 · Foundations11 interview questions
Prerequisites
None
Covers
Java language · Java platform · JDK · JRE · JVM · Java SE · Jakarta EE · Java ecosystem
Related
1.2 Source-to-Execution Lifecycle · 1.3 Language Characteristics · B1V5 Ch1 Java Modules · Book 2 Vol I JVM Architecture · Book 3 Vol VI Jakarta EE Platform
On this page
  1. 1. Concept / Definition
  2. 2. Why It Exists
  3. 3. Core Concepts
  4. 4. How It Works Internally
  5. 5. APIs / Features / Syntax
  6. 6. Practical Examples
  7. 7. Common Problems & Mistakes
  8. 8. Performance & Production Considerations
  9. 9. Architecture & Design Considerations
  10. 10. Interview Questions & Answers
  11. Key Takeaways

1Concept / Definition

"Java" is used for two different things, and most confusion about the platform starts with mixing them up. The Java language is what you write: a set of syntax rules, types and semantics defined by the Java Language Specification (JLS). The Java platform is what runs it: the Java Virtual Machine, a standard class library and a set of development tools. The language is one input to the platform, but not the only one — Kotlin, Scala and Groovy also compile to bytecode and run on the same platform.

"Java" names both a language and the platform that runs it
Figure 1. — "Java" names both a language and the platform that runs it

Three acronyms describe how the platform is packaged. The JVM (Java Virtual Machine) is the engine that loads and executes bytecode. The JRE (Java Runtime Environment) historically meant the JVM plus the class library — everything needed to run a program. The JDK (Java Development Kit) adds the tools needed to build programs: the compiler, packager, diagnostic tools and more.

Two further terms describe *which* platform. Java SE (Standard Edition) is the core platform: the language plus the standard library, currently at release 25. Jakarta EE is a separate set of enterprise specifications — web, persistence, messaging, dependency injection — that sit on top of Java SE. Around all of this sits the Java ecosystem: JDK distributions, build tools, frameworks, other JVM languages and tooling.

2Why It Exists

In the early 1990s, software was compiled separately for every operating system and CPU. A C or C++ program built for Windows on x86 could not run on Solaris on SPARC without recompiling, and often without code changes. Memory errors — dangling pointers, buffer overruns — were a leading cause of crashes and security holes.

Java, released by Sun Microsystems in 1996, was designed to remove both problems at once. Instead of compiling to machine code, the compiler produces bytecode, an instruction set for a virtual machine. Each platform gets its own JVM, and the JVM translates bytecode for the machine it runs on. Memory is managed automatically, pointers are replaced by type-checked references, and code is verified before it runs.

Problem in the 1990sHow the platform design answers it
Recompile for every OS and CPUCompile once to bytecode; a platform-specific JVM executes it
Manual memory management causing crashesJVM allocates and garbage-collects memory
Untrusted code downloaded over networksBytecode verifier, no raw pointers, security checks
Rebuilding common facilities in every projectA large standard class library shipped with the platform
Scaling to enterprise systemsEnterprise specifications (J2EE → Java EE → Jakarta EE) on top of the core

The original applet-in-the-browser use case has disappeared, but the same design choices are why Java dominates server-side enterprise systems today: a stable, portable runtime with a long compatibility record and strong tooling.

3Core Concepts

Java language

The Java language is defined by the Java Language Specification (JLS). The JLS specifies keywords, types, expressions, statements, classes, generics, exceptions and the rules the compiler must enforce. Each Java SE release has a matching JLS edition, so "Java 25" means both a language version and a platform version.

The language evolves through JDK Enhancement Proposals (JEPs). Large features often arrive first as *preview* features, which must be enabled explicitly and can still change, before becoming final. Records, sealed classes and pattern matching all followed this route. Backward compatibility is a strong design value: code written for Java 8 generally compiles and runs on Java 25, with exceptions mostly around removed internal APIs.

Java platform

The Java platform is the combination of three things: the JVM, the Java SE class library and the tools that build and inspect programs. The platform's contract is the bytecode format defined by the Java Virtual Machine Specification (JVMS). Anything that produces valid bytecode — javac, the Kotlin compiler, a bytecode-generation library — can run on it.

JDK — Java Development Kit

The JDK is the complete kit for developing, building and running Java programs. It contains the compiler (javac), the launcher (java), packaging and linking tools (jar, jlink, jpackage), analysis tools (jdeps, javap), an interactive shell (jshell), documentation (javadoc) and diagnostic tools (jcmd, jfr, jstack). It also contains the full runtime: the JVM and the class library.

The JDK contains the tools and the runtime; the runtime contains the class library and the JVM
Figure 2. — The JDK contains the tools and the runtime; the runtime contains the class library and the JVM

All mainstream JDKs are built from the same open-source code base, OpenJDK. Vendors such as Eclipse Adoptium (Temurin), Amazon (Corretto), Oracle, Azul (Zulu), BellSoft (Liberica) and Microsoft publish their own builds. The differences are in support terms, patch timing, licensing and optional extras, not in the core language or library.

JRE — Java Runtime Environment

The JRE was the runtime-only subset of the JDK: JVM plus class library, without the compiler and tools. Up to Java 8, users installed a JRE to run Java applications, and servers typically had a JRE installed globally.

Java 9 introduced the module system and the jlink tool, which can assemble a runtime containing only the modules an application needs. With Java 11, Oracle stopped shipping a separate JRE. The idea of "a runtime" still exists, but in modern practice you either run on a full JDK or build a small custom runtime with jlink. Some distributions, such as Eclipse Temurin, still publish JRE-style builds and container images for convenience.

The JRE as a separate download ended with Java 11; jlink custom runtimes replaced it
Figure 3. — The JRE as a separate download ended with Java 11; jlink custom runtimes replaced it

JVM — Java Virtual Machine

The JVM is an abstract computing machine defined by the JVMS. It is worth separating three meanings of the word:

  • The specification — the JVMS, defining the class file format, bytecode instructions, class loading and verification rules.
  • An implementation — a program that meets the specification. HotSpot is the reference implementation used by most JDKs; Eclipse OpenJ9 and GraalVM are alternatives.
  • An instance — one running JVM process, created when you run the java command, with its own heap, threads and loaded classes.

A JVM implementation has four main parts: the class loader subsystem, which finds and loads classes; the runtime data areas (heap, thread stacks, metaspace); the execution engine, which interprets bytecode and compiles hot code to native instructions with the just-in-time (JIT) compiler; and the garbage collector, which reclaims unreachable objects. Topic 1.2 follows code through each part.

One compiled bytecode file runs on every platform that has a JVM
Figure 4. — One compiled bytecode file runs on every platform that has a JVM

The JVM itself is platform-specific — there is a different HotSpot binary for Linux on ARM64 and for Windows on x86-64. What is platform-neutral is the bytecode it executes. That is the meaning of "write once, run anywhere".

Java SE — Java Standard Edition

Java SE is the standard definition of the core platform: the language (JLS), the virtual machine (JVMS) and the standard API. Each release is defined through the Java Community Process, and OpenJDK is its reference implementation. The Java SE API is organised into modules whose names start with java. — for example java.base (lang, util, io, time, concurrency), java.sql, java.net.http and java.logging. JDK-specific modules start with jdk..

Since Java 10 (March 2018), a new feature release ships every six months, in March and September. Every two years, one release is designated long-term support (LTS) by vendors, receiving security and bug-fix updates for many years. The LTS releases are 8, 11, 17, 21 and 25.

Java SE release train: a feature release every six months, LTS every two years
Figure 5. — Java SE release train: a feature release every six months, LTS every two years

Jakarta EE

Jakarta EE is a set of specifications for enterprise applications built on Java SE: Servlet, Contexts and Dependency Injection (CDI), Persistence (JPA), RESTful Web Services, Messaging, Validation, Transactions, Security and others. It began as J2EE (1999), became Java EE (2006), and moved from Oracle to the Eclipse Foundation in 2017, where it was renamed Jakarta EE.

The move brought one breaking change that still matters in migrations: from Jakarta EE 9 (2020), all package names changed from javax.* to jakarta.*. Jakarta EE is delivered as specifications with compatible implementations — WildFly, Open Liberty, Payara and GlassFish, among others — and as smaller profiles (Web Profile, Core Profile) for lighter runtimes.

Jakarta EE and Spring both build on Java SE; Spring uses selected Jakarta APIs without being a Jakarta EE implementation
Figure 6. — Jakarta EE and Spring both build on Java SE; Spring uses selected Jakarta APIs without being a Jakarta EE implementation

Spring is often placed in the same category, but it is not a Jakarta EE implementation. Spring Framework and Spring Boot run on Java SE with their own programming model, and they use selected Jakarta APIs such as Servlet, Persistence and Validation. Spring Boot 3 and later require the jakarta.* namespace.

Java ecosystem

The ecosystem is everything around the platform that makes it productive in real projects. For an architect it is as important as the language, because most delivery risk sits in the choice and management of these parts.

The Java ecosystem: distributions, build tools, frameworks, alternative JVMs, JVM languages and tooling
Figure 7. — The Java ecosystem: distributions, build tools, frameworks, alternative JVMs, JVM languages and tooling
AreaMain optionsArchitect's question
JDK distributionsTemurin, Corretto, Oracle JDK, Zulu, Liberica, Microsoft Build of OpenJDKWho patches us, how fast, and under what licence?
Build and dependenciesMaven, Gradle; Maven CentralHow do we control versions and supply-chain risk?
FrameworksSpring Boot, Jakarta EE runtimes, Quarkus, MicronautWhich programming model fits the team and the deployment target?
Alternative JVMsEclipse OpenJ9; GraalVM (including native image)Do startup time or memory footprint justify a non-default runtime?
JVM languagesKotlin, Scala, Groovy, ClojureIs a second language worth the hiring and tooling cost?
Tools and observabilityIntelliJ IDEA, Eclipse, VS Code; JFR, JDK Mission Control, VisualVMCan we diagnose production issues without restarting services?

4How It Works Internally

When you type java -jar app.jar, the java executable is a small native launcher. It locates the JVM shared library (libjvm.so on Linux, jvm.dll on Windows), creates a JVM instance inside the same process, and hands it the main class. The bootstrap class loader then reads the core modules from a single optimised file, lib/modules, rather than from hundreds of JAR files as in Java 8.

Directory in a JDKContents
bin/Launchers and tools: java, javac, jar, jlink, jcmd, …
lib/The JVM library, the modules image (lib/modules), security files
conf/Editable configuration: security policy, logging, network properties
jmods/Packaged modules used by jlink (some builds omit this since JDK 24, JEP 493)
include/C headers for native interfaces
legal/Licence files

Two layers of specification keep implementations interchangeable. The JLS governs what javac must accept and produce; the JVMS governs what every JVM must execute. A JDK build that claims Java SE compatibility must pass the Technology Compatibility Kit (TCK). This is why an application built with Corretto normally runs unchanged on Temurin: the code bases are the same, and the behaviour is specified and tested.

5APIs / Features / Syntax

Core JDK tools

ToolPurposeTypical use
javaLaunch a JVM and run a class, JAR or single source filejava -jar app.jar
javacCompile .java to .classjavac -d out src/**/*.java
jarCreate and inspect JAR archivesjar --create --file app.jar -C out .
jlinkBuild a custom runtime imagejlink --add-modules java.base,…
jdepsShow module and package dependenciesjdeps --print-module-deps app.jar
jshellInteractive REPLjshell
javapDisassemble class filesjavap -c -v Order.class
jcmdSend diagnostic commands to a running JVMjcmd <pid> VM.version
jfrRecord and inspect Flight Recorder datajcmd <pid> JFR.start
jpackageCreate native installersjpackage --input target …

Platform information at runtime

The Runtime.version() API returns a structured version object, and system properties expose the vendor, JVM and operating system. These are the standard way for an application or health endpoint to report the platform it is actually running on.

Version API
Runtime.Version v = Runtime.version();   // e.g. 25.0.1+8-LTS
int feature = v.feature();                // 25
String vendor = System.getProperty("java.vendor");
String vmName = System.getProperty("java.vm.name");
// vmName e.g. "OpenJDK 64-Bit Server VM"

6Practical Examples

Example 1 — Inspect the installed platform

Terminal — output varies by vendor and patch level
$ java -version
openjdk version "25.0.1" 2025-10-21 LTS
OpenJDK Runtime Environment Temurin-25.0.1+8 (build 25.0.1+8-LTS)
OpenJDK 64-Bit Server VM Temurin-25.0.1+8 (build 25.0.1+8-LTS,
  mixed mode, sharing)
$ javac -version
javac 25.0.1
$ java --list-modules | head -5
java.base@25.0.1
java.compiler@25.0.1
java.datatransfer@25.0.1
java.desktop@25.0.1
java.instrument@25.0.1

Read the output carefully: the version (25.0.1), the vendor build (Temurin), the VM (64-Bit Server VM, i.e. HotSpot), and "mixed mode" — interpreter plus JIT. "Sharing" means class data sharing is active, which improves startup (see 1.2).

Example 2 — Report platform details from code

PlatformInfo.java
public class PlatformInfo {

    public static void main(String[] args) {
        Runtime rt = Runtime.getRuntime();
        Runtime.Version v = Runtime.version();

        System.out.println("Java version : " + v);
        System.out.println("Feature      : " + v.feature());
        System.out.println("Vendor       : " + prop("java.vendor"));
        System.out.println("VM           : " + prop("java.vm.name"));
        System.out.println("OS / arch    : " + prop("os.name")
                + " / " + prop("os.arch"));
        System.out.println("CPUs         : " + rt.availableProcessors());
        System.out.println("Max heap MB  : " + rt.maxMemory() / (1024 * 1024));
    }

    private static String prop(String key) {
        return System.getProperty(key);
    }
}

This kind of output is useful in a service's startup log or an actuator-style info endpoint. When a production incident is caused by a different JDK than expected — for example an old base image — the log line makes the cause visible immediately.

Example 3 — A Java 25 compact source file

Hello.java
// Hello.java — no class declaration, no static main (Java 25, JEP 512)
void main() {
    IO.println("Running on Java " + Runtime.version().feature());
}
TERMINAL
$ java Hello.java
Running on Java 25

A service rarely needs the whole JDK. jdeps finds the modules it uses, and jlink assembles a runtime containing only those modules. This replaces the old separate JRE.

Terminal
# 1. Which Java SE modules does the application need?
$ jdeps --print-module-deps --ignore-missing-deps \
    --multi-release 25 target/app.jar
java.base,java.logging,java.naming,java.sql

# 2. Build a runtime with only those modules
$ jlink --add-modules java.base,java.logging,java.naming,java.sql \
    --strip-debug --no-man-pages --no-header-files \
    --compress zip-6 --output build/runtime

# 3. Run the application on the custom runtime
$ build/runtime/bin/java -jar target/app.jar

A full JDK is typically a few hundred megabytes; a trimmed runtime for a typical service is usually a fraction of that. The exact saving depends on the modules needed, so measure it for your own application.

Example 5 — Multi-stage container image

Dockerfile
# Stage 1: build a custom runtime using the full JDK
FROM eclipse-temurin:25-jdk AS jre-build
COPY target/app.jar /app/app.jar
RUN jlink --add-modules java.base,java.logging,java.naming,java.sql \
      --strip-debug --no-man-pages --no-header-files --compress zip-6 \
      --output /opt/runtime

# Stage 2: small final image with only the runtime and the application
FROM debian:bookworm-slim
COPY --from=jre-build /opt/runtime /opt/runtime
COPY --from=jre-build /app/app.jar /app/app.jar
ENTRYPOINT ["/opt/runtime/bin/java", "-jar", "/app/app.jar"]

7Common Problems & Mistakes

Mistake or misconceptionRealityWhat to do
"Users need to install a JRE to run our app"No standalone Oracle JRE since Java 11Ship a jlink runtime or a container image with the runtime included
Treating JDK, JRE and JVM as synonymsThey are nested layers with different contentsUse the terms precisely in design documents and runbooks
Building on one JDK and running on anotherClass-version errors or behaviour differencesPin the same feature version in build, CI and runtime images
Mixing javax.* and jakarta.* librariesJakarta EE 9 renamed every packageUpgrade dependencies together; use migration tooling for source changes
Assuming Oracle JDK is "the real Java"All mainstream JDKs build from OpenJDK and pass the TCKChoose on support, patch cadence and licence terms
JAVA_HOME and PATH pointing at different JDKsTools and the runtime disagree on the versionCheck java -version, javac -version and echo $JAVA_HOME together
Staying on a non-LTS release in productionUpdates stop after six monthsUse LTS releases for production unless there is a clear reason not to

8Performance & Production Considerations

  • Patch cadence. Security updates for supported releases arrive quarterly (January, April, July, October). Production images should be rebuilt and redeployed on that cycle.
  • Distribution choice. Pick one distribution per organisation and standardise it across build agents, developer machines and base images. Mixed distributions are rarely a functional problem but always an operational one.
  • Image size and startup. A jlink runtime reduces image size and pull time. Class data sharing, and the ahead-of-time cache introduced in recent releases, reduce startup time (see 1.2).
  • Container awareness. Modern JVMs read container CPU and memory limits and size the heap and thread pools from them. Very old runtimes did not, which caused out-of-memory kills in containers.
  • Observability. Keep jcmd and Java Flight Recorder available through some route, even when the production image is trimmed; they are the first tools used in a JVM incident.

9Architecture & Design Considerations

At solution level, "which Java platform" is really three decisions: the Java version and upgrade policy, the JDK distribution and support model, and the application runtime model.

Runtime modelFits whenTrade-offs
Plain Java SELibraries, batch jobs, CLI tools, very small servicesFew dependencies; you build infrastructure concerns yourself
Spring Boot on Java SEMost enterprise services and APIs; large hiring poolRich ecosystem; larger memory and startup than minimal runtimes
Jakarta EE runtimeOrganisations standardised on application servers or specsVendor-neutral specifications; smaller modern community than Spring
Quarkus / MicronautContainer-first services where startup and memory matterBuild-time optimisation; some libraries need adaptation
GraalVM native imageServerless or fast-scaling workloads needing millisecond startupLonger builds, reflection configuration, different profiling model

10Interview Questions & Answers

Q1Knowledge

What is the difference between the JDK, the JRE and the JVM?

The JVM executes bytecode. The JRE was the JVM plus the standard class library — everything needed to run a program. The JDK is the JRE plus development tools such as javac, jar, jlink and jcmd. They are nested layers: JDK contains the runtime, which contains the JVM.

Since Java 11, Oracle no longer ships a separate JRE; you run on a JDK or on a custom runtime built with jlink.

Q2Knowledge

What is the difference between Java SE and Jakarta EE?

Java SE is the core platform: the language, the JVM specification and the standard library. Jakarta EE is a set of enterprise specifications (Servlet, CDI, Persistence, REST, Messaging and others) built on top of Java SE and implemented by application runtimes such as WildFly or Open Liberty.

Q3Understanding

Why is the JVM called platform-specific when Java is called platform-independent?

The bytecode is platform-independent: the same .class file runs anywhere. The JVM that executes it is a native program built separately for each operating system and CPU, and it translates the bytecode into that machine's instructions. Portability is achieved by moving the platform-specific part out of the application and into the JVM.

Q4Understanding

What are the JLS and the JVMS, and why does the distinction matter?

The JLS specifies the Java language — what the compiler must accept and how programs behave. The JVMS specifies the virtual machine — the class-file format, bytecode instructions, loading and verification. The distinction matters because other languages target the JVMS without the JLS, and because runtime behaviour such as class loading is governed by the JVMS, not by the language.

Q5Application

How would you reduce the size of a Java service's container image?

Use jdeps --print-module-deps to find the modules the application needs, then jlink to build a runtime with only those modules, stripping debug information, man pages and headers. Use a multi-stage build so the final image contains only the runtime and the application, on a slim base image.

Keep a separate route for diagnostics — a debug image or an ephemeral container with jcmd — so that trimming the image does not remove your ability to troubleshoot.

Q6Application

A service fails at startup with UnsupportedClassVersionError. What happened and how do you fix it?

Some class in the application or a dependency was compiled for a newer Java release than the runtime. The class-file major version is higher than the JVM supports. Fix it by aligning versions: run on a runtime at least as new as the compilation target, or compile with --release set to the runtime version. Check that CI, build images and runtime images use the same feature version.

Q7Senior Engineer

Our organisation uses three different JDK distributions across teams. Is that a problem?

Functionally it is rarely a problem, because all mainstream distributions build from OpenJDK and pass the TCK. Operationally it is a problem: three patch schedules, three sets of base images, and inconsistent behaviour for vendor-specific options or bundled extras. Standardising on one distribution per organisation simplifies patching, security scanning and incident diagnosis.

Q8Senior Engineer

What changes when you migrate an application from Java EE 8 to Jakarta EE 10 or Spring Boot 3?

The main breaking change is the namespace: javax.* enterprise packages become jakarta.*. Every affected import, configuration file and dependency must change together; a library still on javax cannot be mixed in. Plan it as a coordinated upgrade using migration tooling for source changes, and check every third-party dependency for a Jakarta-compatible version before starting.

Q9Technical Architect

How would you choose between Spring Boot, a Jakarta EE runtime and Quarkus for a new service?

Start from constraints rather than preference. Consider team skills and hiring, the deployment target (long-running containers, autoscaling, serverless), startup and memory requirements, existing organisational standards, and the libraries the service depends on. Spring Boot is the default for most enterprise services because of its ecosystem; Jakarta EE fits organisations with specification-based standards; Quarkus or native images fit when fast startup and small footprint are hard requirements. Record the decision and the trade-offs in an ADR.

Q10Technical Architect

What should an organisation's Java version policy look like?

Standardise on LTS releases for production, with a planned upgrade to each new LTS within a defined window, for example 12–18 months. Keep build and runtime on the same feature release, apply quarterly security updates automatically through base-image rebuilds, and track end-of-support dates per application. This keeps upgrades small and regular instead of rare and risky.

Q11Solution Architect

A bank asks you to justify Java as the platform for a new core payments system expected to live 15 years. How do you argue it?

Focus on longevity and risk. Java has a long backward-compatibility record, a six-monthly release cycle with LTS releases every two years, multiple independent vendors building from OpenJDK, and commercial support options, which reduces vendor lock-in and supports regulatory requirements.

Add the ecosystem: mature frameworks, observability tooling such as Flight Recorder, a large hiring pool and extensive security tooling. Then state the trade-offs honestly — higher memory than some runtimes, warm-up behaviour, and the need for disciplined dependency and upgrade management — and show how the architecture addresses them, for example with LTS upgrade policy, standard base images and capacity planning.

Key Takeaways

  • "Java" is both a language (JLS) and a platform (JVM + library + tools); bytecode is the contract between them.
  • JDK contains the runtime, which contains the JVM. There is no separate Oracle JRE since Java 11; jlink builds custom runtimes.
  • Java SE is the core platform; Jakarta EE is an enterprise specification layer on top; Spring uses selected Jakarta APIs but is not an implementation.
  • All mainstream JDKs build from OpenJDK. Choose a distribution for support, patching and licensing, and standardise on it.
  • Use LTS releases (current baseline: Java 25) and upgrade LTS to LTS on a plan.

Coverage checklist

Java language ✔ · Java platform ✔ · JDK ✔ · JRE ✔ · JVM ✔ · Java SE ✔ · Jakarta EE ✔ · Java ecosystem ✔

Newsletter

Get new tutorials every week

New ArchitectMind tutorials and interview questions, once a week. No spam, unsubscribe anytime.

Almost done! Check your inbox and click the confirmation link to complete your subscription.