Course outline

Java / Basic / Lesson 1

JDK tools, compilation, and launching

Follow a Java source file through compilation and execution while keeping compiler, runtime, classpath, and version requirements distinct.

About 5 min readContent reviewed
On this page

Lesson goals

  • Explain source, bytecode, and the JVM.
  • Compile and launch a complete Java 17 program.
  • Diagnose names and version boundaries.

Separate the compiler from the runtime

A JDK contains development tools such as javac and a Java runtime. javac checks source rules and produces class files containing bytecode; the java launcher starts a JVM and loads classes. The JVM executes the program, potentially compiling frequently executed code to machine instructions. Compilation success proves type and syntax checks passed, not that the business calculation is correct.

Check both javac -version and java -version because PATH can select different installations. This course uses the traditional Java 17 entry point and no preview features. When deploying, record the target release and actual runtime separately. A newer compiler can target older releases with --release, which checks the supported platform API as well as the language target.

Read a complete entry point

Save this complete program as Main.java. The public top-level class name matches the filename. The launcher invokes public static void main(String[] args): public exposes it, static associates it with the class, void means no return value, and args holds command-line strings. These words establish a launch contract; they do not need to appear on every method you later write.

The program prints one line followed by a newline. System.out is the standard output stream and println formats the supplied text. Predict the output before running it, then compare exact characters. Keep code in a new temporary directory so stale class files from another exercise cannot masquerade as the result of the current compilation.

java A complete Java 17 entry point
public class Main {

 public static void main(String[] args) throws Exception {
System.out.println("Hello, Java 17");
 }
}
Expected output
Hello, Java 17

The line is deterministic and requires no input, files, network, or external library.

Keep source names and binary names straight

Compile with javac --release 17 Main.java and launch with java -cp . Main. The compiler receives a source filename, while the launcher receives a class name without .class. The dot classpath means the current directory is a search root. A packaged class uses its qualified name and a directory layout rooted at the classpath; simply moving a class file does not rename its package.

Read the first compiler diagnostic and its location before changing unrelated code. A successful old build does not justify running after a failed new compile. Separate source and output directories as projects grow, and make the build stop on failure. Shell command examples are explanatory tool invocations; the public website itself never executes them.

Observe command-line arguments as data

Arguments arrive as strings, not automatically parsed numbers. With no arguments, args.length is zero, so reading args[0] immediately would fail. This example reports the count and uses a safe fallback. The fallback is an explicit product choice: a command that requires a filename should reject missing input instead of silently inventing one.

Separate environment-dependent facts from portable behavior. The actual Java version string varies by installation and should not be fabricated as a universal output. The count example has a fixed result only when launched with no extra arguments, as in the course validation. Later exercises will validate argument types and business ranges before calculating.

java Arguments with an explicit missing-input policy
public class Main {

 public static void main(String[] args) throws Exception {
System.out.println(args.length);
System.out.println(args.length == 0 ? "no input" : args[0]);
 }
}
Expected output
0
no input

Validation launches this program without arguments, so the first line is zero and the second follows the fallback branch.

Label later language features explicitly

Java 17 supports records, sealed classes, and switch expressions as standard features. Virtual threads became a standard feature in Java 21 and are taught later with an explicit version boundary. Compact source files and expanded instance main methods became permanent in Java 25; their shorter entry syntax is intentionally outside the Java 17 examples. None of these statements implies a newest-release recommendation.

A reproducible learning record includes source, command, target release, runtime, expected output, and observed result. Keep successful examples complete and small, and label fragments or deliberately broken code non-runnable. When copying a newer tutorial, check its API and feature requirements before blaming the installed compiler for rejecting unsupported syntax.

Common errors and fixes

class Main is public, should be declared in a file named Main.java

Why it happens
The public class and source filename differ.
How to fix it
Rename the file or class consistently.
Prevent it next time
Keep one exercise in an isolated directory with a matching filename.

Could not find or load main class Main

Why it happens
The binary name or classpath root is wrong, or compilation failed.
How to fix it
Confirm successful compilation and launch the qualified class name from the correct root.
Prevent it next time
Separate compile and run steps and stop on build failure.

UnsupportedClassVersionError

Why it happens
The runtime cannot load the class-file version.
How to fix it
Use a compatible runtime or rebuild for the supported release.
Prevent it next time
Record compiler target and deployment runtime together.

Check your understanding

1. Explain why java Main.class is not the normal command after compilation.

Show worked solution

The launcher expects a binary class name, Main, rather than a class-file pathname. javac accepts Main.java. With a package, pass its qualified name and choose the classpath root above the package directories.

2. A developer has javac 21 and java 17. How can this baseline program be built for Java 17?

Show worked solution

Use javac --release 17 Main.java and validate using Java 17. The release option checks the target platform API as well as source compatibility. Do not introduce a Java 21-only API into the code and expect a target flag alone to make it available.

Key takeaways

  • A compiler target and a runtime are separate facts.
  • Launch a binary class name from a valid search root.
  • Later features need explicit version labels.

Official references