Run Java Locally

The Course
•
5 min read

The whole core course works in your browser. This optional local step shows that the source files are ordinary Java, not code that only makes sense inside the website. You can download them, inspect them and run them with a Java Development Kit (JDK). The browser’s engine follows a documented subset of Java 25, so JDK 25 is the closest reference environment for these lessons.

Download and inspect

Download the study planner or the earlier two-file session example. Extract a ZIP before opening a terminal in its folder. The planner contains Main.java, Planner.java, Session.java, PlannerTest.java, sample-input.txt and a README explaining its contract. There is no external dependency or build tool.

Use the official Java learning site for installation help. Install a JDK, not only an execution runtime, because javac is the compiler. A terminal is an app where you type commands and press Enter to run them. You can use Terminal on macOS, a terminal on Linux, or PowerShell/Command Prompt on Windows. Type each line below separately; do not type the code-fence labels. Check both tools in your terminal:

java --version
javac --version

If either command is missing, finish installation or correct the terminal’s PATH. PATH is the list of folders your terminal searches for commands. The JDK installation guide explains how to put its tools there. An editor plugin alone does not necessarily install a JDK. Open a new terminal after changing PATH. If setup is taking you away from Java practice, continue in the browser and return to this optional section later.

Compile, test, then run

Open your terminal in the extracted study-planner folder. Many file managers offer an Open in Terminal action. Otherwise use cd (change directory) followed by the folder’s full path in double quotes; the actual path depends on where you extracted it. Then compile all four source files and run the test entry:

javac Main.java Planner.java Session.java PlannerTest.java
java PlannerTest

javac creates .class files; it does not run main. java PlannerTest launches the compiled test class, with no .java suffix. After a successful compile, the test program should print All planner checks passed. Stop and read the error if compilation fails; otherwise old .class files could confuse your next run.

In a macOS/Linux shell or Windows Command Prompt, run the normal entry with the supplied input file:

java Main < sample-input.txt

In PowerShell, use Get-Content sample-input.txt | java Main instead. The file’s lines become standard input; the model still does not save a plan to disk. Without redirection, a local terminal can provide interactive input until EOF; the browser uses its prefilled box instead. README explains the relevant EOF keys.

The browser still runs the same model checks Java
import java.util.Scanner; public class Main { public static void main(String[] args) { Scanner input = new Scanner(System.in); Planner planner = new Planner(); // Two lines per session: a topic, then whole-number minutes. while (input.hasNextLine()) { String topic = input.nextLine(); if (!input.hasNextLine()) { System.out.println("Missing minutes for: " + topic); break; } String minutesText = input.nextLine(); try { int minutes = Integer.parseInt(minutesText.trim()); planner.add(topic, minutes); } catch (NumberFormatException error) { System.out.println("Skipped: minutes must be a whole number"); } catch (IllegalArgumentException error) { System.out.println("Skipped: " + error.getMessage()); } catch (IllegalStateException error) { System.out.println(error.getMessage()); break; } } // This demo completes the first accepted session, if there is one. planner.complete(0); System.out.println(planner.report()); } } import java.util.ArrayList; public class Planner { private final ArrayList<Session> sessions = new ArrayList<>(); public void add(String topic, int minutes) { if (sessions.size() >= 100) { throw new IllegalStateException("Plan is full"); } // Construct and validate before changing the list. Session session = new Session(topic, minutes); sessions.add(session); } public int size() { return sessions.size(); } public boolean complete(int index) { if (index < 0 || index >= sessions.size()) { return false; } sessions.get(index).complete(); return true; } public int plannedMinutes() { int total = 0; for (Session session : sessions) { total += session.minutes(); } return total; } public int completedMinutes() { int total = 0; for (Session session : sessions) { if (session.isDone()) { total += session.minutes(); } } return total; } public String report() { int planned = plannedMinutes(); int completed = completedMinutes(); return size() + " sessions, " + completed + "/" + planned + " min complete"; } } public class Session { private final String topic; private final int minutes; private boolean done; public Session(String topic, int minutes) { if (topic == null || topic.trim().isEmpty()) { throw new IllegalArgumentException("Topic is required"); } if (minutes < 1 || minutes > 240) { throw new IllegalArgumentException("Minutes must be 1 to 240"); } this.topic = topic.trim(); this.minutes = minutes; } public String topic() { return topic; } public int minutes() { return minutes; } public boolean isDone() { return done; } public void complete() { // Completing a session twice still counts it only once. done = true; } } public class PlannerTest { public static void main(String[] args) { Planner empty = new Planner(); check("empty report", empty.report().equals("0 sessions, 0/0 min complete")); check("empty completion", !empty.complete(0)); Planner planner = new Planner(); planner.add(" Java ", 25); planner.add("Reading", 10); check("planned total", planner.plannedMinutes() == 35); check("initial completion", planner.completedMinutes() == 0); check("complete first", planner.complete(0)); check("complete again", planner.complete(0)); check("count once", planner.completedMinutes() == 25); check("negative index", !planner.complete(-1)); check("index at size", !planner.complete(2)); check("report", planner.report().equals("2 sessions, 25/35 min complete")); Session normalized = new Session(" Java ", 25); check("trim topic", normalized.topic().equals("Java")); check("new session", !normalized.isDone()); check("separate planner", empty.plannedMinutes() == 0); expectInvalid(planner, null, 25); expectInvalid(planner, " ", 25); expectInvalid(planner, "Bad", 0); expectInvalid(planner, "Bad", 241); check("failed additions do not change size", planner.size() == 2); check("failed additions do not change total", planner.plannedMinutes() == 35); Planner full = new Planner(); for (int index = 0; index < 100; index++) { full.add("Topic", 240); } check("bounded total", full.plannedMinutes() == 24000); boolean rejected = false; try { full.add("Extra", 1); } catch (IllegalStateException error) { rejected = true; } check("full plan rejects addition", rejected); check("full plan unchanged", full.size() == 100); System.out.println("All planner checks passed"); } private static void expectInvalid(Planner planner, String topic, int minutes) { boolean rejected = false; try { planner.add(topic, minutes); } catch (IllegalArgumentException error) { rejected = true; } check("invalid addition rejected", rejected); } private static void check(String label, boolean condition) { if (!condition) { throw new AssertionError(label); } } }
Check your prediction
All planner checks passed

This gives you an installation-free reference while setting up local Java. The ZIP and file tabs come from the same maintained sources. If a later edit changes a rule, rerun checks in both environments.

Source and results are different artifacts Java
public class Main {
    public static void main(String[] args) {
        String sourceName = "Main.java";
        String compiledName = "Main.class";

        System.out.println(sourceName);
        System.out.println(compiledName);
    }
}
Check your prediction
Main.java
Main.class

A .java file is source you edit. A .class file is compiled output. These are just explanatory Strings; creating these variables does not create files or invoke the compiler.

Your turn

Exercise

Separate calculation from presentation locally

As a small independent program, write total(int[] minutes) and a main that prints Total: 35 for {25,10}. Run it in the browser; optionally save it as Main.java, compile and run locally. Empty input should total 0.

Your workspace Java
public class Main {
    public static void main(String[] args) {
        // Call a calculation helper and print a labeled result.
    }

    // Define total.
}
Hint 1: the idea

Changing the execution environment should not require changing the calculation contract.

Hint 2: a first step

Keep the helper inside Main and return a number. Build the output label only in main.

Show one solution
public class Main {
    public static void main(String[] args) {
        int total = total(new int[] {25, 10});
        System.out.println("Total: " + total);
    }

    static int total(int[] values) {
        int sum = 0;

        for (int value : values) {
            sum += value;
        }

        return sum;
    }
}
Total: 35

Change it and explain

Make a small source edit, compile again and rerun both the tests and the demo. Record the commands and expected output in your own words. Do not include your JDK installation, generated .class files or unrelated personal data in a project submission; the source and instructions should be sufficient.

The browser’s multi-file mode follows source-launcher behavior and may leave unused helpers unchecked. Explicitly compiling all files locally can reveal errors in an unused source too. That is a difference in how you launched the build, not a rule that Java types work differently online.

Was this article helpful?

Your response is saved on this device.