عرض عملي: إصلاح خمسة برامج معطّلة من رسائل المترجم
في هذا الدرس 11 موضوعات
هذا الدرس متاح حاليًا باللغة الإنجليزية فقط، ولم تُنشر نسخته العربية بعد.
Lesson Overview
This is a guided demo. You will follow along on your own machine and practise the fix loop from Lesson 5 on five broken programs, one at a time, using only the compiler's messages to find each fault. At the end, a sixth program contains the planned mistake of this demo: fixing the first error and assuming you are done.
The five faults are the five you have learned: a missing semicolon, a misspelled name, a missing closing brace, a wrong main line, and an unclosed string. The programs here are close cousins of the five that the module's lab gives you. Do the demo first, then the lab will feel like a repeat of something you already know.
Why this matters: a fast, calm fix loop is what separates a frustrating afternoon from a five-minute fix. The loop you practise here, run the tool, read the first message, change one thing, run again, is the same one you will use on much larger problems later.
This lesson builds on Lessons 1 to 5 and on the terminal skills from BEG-006 and BEG-007 (javac, java, creating files). If you prefer, you can use IntelliJ IDEA instead of the terminal. Menu names differ between versions, so look for the equivalent actions.
Learning Objectives
By the end of this lesson you will be able to:
- Run the fix loop (compile, read the first message, fix one thing, recompile) without guessing.
- Fix a missing semicolon, a wrong-case name, a missing closing brace, a wrong
mainsignature, and an unclosed string from the messages alone. - Tell whether a message came from
javacor fromjava. - Explain why a program with two mistakes needs two rounds, and why a silent
javacdoes not prove the program is right. - Record each message, its line, and its fix in a short log.
Written Explanation
Setup
Make a new folder for this demo and open a terminal in it. Create the five files below. For each one, the file name is the class name plus .java. The messages shown are what JDK 21 printed for these exact files. Yours may differ slightly in wording, spacing, or line positions.
You will work in this order:
- Compile (
javac P1.java). - Read the first message.
- Fix one thing.
- Compile again.
- When
javacis silent, run (java P1) and check the output.
Keep a small log: file, message, line, fix.
Program 1: the missing semicolon
public class P1 {
public static void main(String[] args) {
System.out.println("Ready");
System.out.println("Cairo")
}
}Compile with javac P1.java. You should see:
P1.java:4: error: ';' expected
System.out.println("Cairo")
^
1 errorRead it: file P1.java, line 4, the compiler expected a semicolon, and the caret sits right after the closing parenthesis. The fix is to add ; at the end of line 4. Compile again: silent. Run java P1:
Ready
CairoProgram 2: the misspelled name
public class P2 {
public static void main(String[] args) {
system.out.println("Ready");
}
}javac P2.java says:
P2.java:3: error: package system does not exist
system.out.println("Ready");
^
1 errorRead it: Java met the name system followed by a dot, took it for a package, and found none. The message names system, so check its spelling and capital letters against the working line from Lesson 3: it is System. Change the first letter to a capital S, compile (silent), and run: Ready.
If your JDK says cannot find symbol here instead, the fix is the same. Both messages mean "I do not know this name".
Program 3: the missing closing brace
public class P3 {
public static void main(String[] args) {
System.out.println("Ready");
}P3.java:4: error: reached end of file while parsing
}
^
1 errorRead it: the compiler hit the end of the file while a block was still open. The caret is at the last line, but the cause is above. Use the brace count from Lesson 2: the file has two { (class and main) and only one }. The closing brace of the class is missing. Add } on a new line at the end. Compile, run: Ready.
Program 4: the wrong main line
public class P4 {
public static void main(String args) {
System.out.println("Ready");
}
}javac P4.java prints nothing. The program is valid Java, so it compiles. Does that mean it works? Run it:
Error: Main method not found in class P4, please define the main method as:
public static void main(String[] args)
or a JavaFX application class must extend javafx.application.ApplicationRead it: the message came from java, not from javac, so it is a launch error. The launcher wants exactly the line it shows, and ours has String args without the square brackets. Change it to String[] args, compile, run: Ready.
Program 5: the unclosed string
public class P5 {
public static void main(String[] args) {
System.out.println("Ready);
}
}P5.java:3: error: unclosed string literal
System.out.println("Ready);
^
1 errorRead it: the caret is under the quote that opened the text. A string must close on the same line, and this one did not. Add the closing " before the ): System.out.println("Ready");. Compile, run: Ready.
Program 6: the planned mistake
Now the trap. Create P6.java:
public class P6 {
public static void main(String[] args) {
System.out.println("Ready")
System.out.printn("Go");
}
}Compile it, read the message, and fix only what it names:
P6.java:3: error: ';' expected
System.out.println("Ready")
^
1 errorAdd the semicolon after println("Ready") and stop there, thinking you are finished. A beginner would now run java P6. But recompile first, as the loop says, and you see:
P6.java:4: error: cannot find symbol
System.out.printn("Go");
^
symbol: method printn(String)
location: variable out of type PrintStream
1 errorThe second mistake was hidden behind the first. The message says Java found no method named printn in the type of System.out, so it is a typo. Change printn to println, compile (silent), and run:
Ready
GoThe message at the first compile said "1 error", yet the file had two mistakes. The error count tells you what the compiler has found so far, not what is wrong with the file. That is why the habit is: fix, recompile, and read again, until javac is silent and the output is what you intended.
Your log
Here is what a good log looks like after the demo:
| Program | Printed by | Message | Line | Fix |
|---|---|---|---|---|
| P1 | javac | ';' expected | 4 | Add ; |
| P2 | javac | package system does not exist | 3 | system to System |
| P3 | javac | reached end of file while parsing | 4 | Add the closing } |
| P4 | java | Main method not found | none | String to String[] |
| P5 | javac | unclosed string literal | 3 | Add the closing " |
| P6 | javac, twice | ';' expected, then cannot find symbol | 3, then 4 | Fix one, recompile, fix the next |
Using the IDE
In IntelliJ IDEA the same faults are marked in the editor as you type, usually with a red underline, and the message appears when you hover over it. The build output panel shows the compiler messages when you run the program. The idea is the same: read the first message, change one thing, and run again. The exact colours, menu names, and wording of IDE messages differ from javac's and vary by version, so confirm each fix with the real compiler output when you are unsure.
Examples
Example 1: a clean fix loop (simple)
You get ';' expected at line 4. You look at line 4, see the statement without ;, add it, and recompile. Silent. One round, one fix, nothing guessed.
Example 2: the report is at the end of the line (practical)
In this program, the second println lacks its semicolon:
System.out.println("Total");
System.out.println("Done")
}The compiler notices the problem only when it reads the } that follows, so it reports ';' expected for the "Done" line, with the caret just after ). If the named line looks fine to you, look at the line directly above it too. Then recompile.
Example 3: one round fixes two, the next shows a third (realistic)
Take the program Q4 from Exercise C1. The first compile reports two errors, ';' expected on line 3 and unclosed string literal on line 5. You fix both and recompile. Now a third error appears: cannot find symbol for printn on line 4. It was there all along, hidden. That is not a regression. In real projects a build can show new errors after each fix, and that usually means progress. Keep reading from the first message.
Backend Insight
In a team, a build runs automatically on a server, and a broken build blocks everyone's work. The person who broke it is expected to read the log, find the first error, and fix it quickly. The five faults in this demo are small, but the routine is the real skill: take the first message, locate the line, make one change, and run the build again.
Also remember P4. A program can build successfully and still fail at launch because of a configuration mistake. Backend teams meet this all the time: the build is green, the service does not start, and the answer is in the first error line of the start-up log.
Common Mistakes
Mistake 1: Fixing several things before recompiling
If something is still wrong, you will not know which of your changes caused it. Change one thing at a time.
Mistake 2: Stopping at the first fix
As P6 showed, one fix may uncover another. Stop only when javac is silent and the program prints what you expected.
Mistake 3: Running the program after a failed compile
Read the compile output first. A leftover .class from an earlier success can run the old version, as you saw in BEG-007.
Mistake 4: Thinking silence from javac means success
P4 compiles and then fails at launch. Run the program and check its output.
Mistake 5: Retyping the whole file
When a message points at a line, change that line. Retyping can add new mistakes and teaches you nothing about the old one.
Exercises
Try each exercise yourself before opening the solutions. Hands-on items must be done on your machine.
Level A: Foundation
A1. Name the five faults in this demo and the message (or launch error) each produces.
أظهر الحل A1
A1. Missing semicolon: ';' expected. Misspelled name or wrong case: package system does not exist or cannot find symbol. Missing closing brace: reached end of file while parsing. Wrong main line: no javac message, then Main method not found from java. Unclosed string: unclosed string literal.
A2. Which of the five faults is not reported by javac? Which command reports it?
أظهر الحل A2
A2. The wrong main line. The java command reports it when you run the class.
A3. Why is "1 error" not proof that the file has only one mistake?
أظهر الحل A3
A3. The compiler may stop at a grammar problem before it checks names, so a second mistake can be hidden. In P6 the first compile said "1 error", and after fixing it a second error appeared.
Level B: Application
B1. Create the file Q1.java below. Compile, read, fix using only the message, and record the message and the fix.
public class Q1 {
public static void main(String[] args) {
System.out.println("Tea");
System.out.println("Cake")
System.out.println("Juice");
}
}أظهر الحل B1
B1. The message is ';' expected on line 4, after System.out.println("Cake"). Add ;. The output is Tea, Cake, Juice on separate lines.
B2. Create Q2.java below. Compile, read, fix, and record. After the fix, the program should print Open.
public class Q2 {
public static void main(String[] args) {
System.Out.println("Open");
}
}أظهر الحل B2
B2. In JDK 21 the message is cannot find symbol with symbol: variable Out and location: class System. The wrong capital O is the cause. Change Out to out. Output: Open.
B3. Create Q3.java below, compile it, and run it. What happens, which command reports it, and what is the fix?
public class Q3 {
public void main(String[] args) {
System.out.println("Start");
}
}أظهر الحل B3
B3. It compiles silently, because the method has a legal name and signature. Running it prints a launch message from java, Error: Main method is not static in class Q3, please define the main method as: followed by public static void main(String[] args) (JDK 21; other versions may word it differently). The fix is to add static.
Level C: Challenge
C1. Create Q4.java with the three mistakes below. Predict the order in which you will meet the messages, then fix them one at a time, recompiling after each. Record how many rounds it took.
public class Q4 {
public static void main(String[] args) {
System.out.println("Hello")
System.out.printn("World");
System.out.println("Done);
}
}أظهر الحل C1
C1. In JDK 21 the first compile reports two errors: ';' expected at line 3 and unclosed string literal at line 5. After you fix both, the second compile reports cannot find symbol for printn at line 4. So it takes two rounds of fixing, then a silent third compile. Other JDK versions may group the errors differently, which is why the habit is to recompile after each fix. The final program prints Hello, World, and Done on separate lines.
C2. A teammate says: "javac only printed one error, so I only have one bug." Write a two-sentence reply that explains why they should not rely on that, using something from this demo.
أظهر الحل C2
C2. Reply: the count only covers the errors the compiler has reached so far, and a grammar error can stop it before it checks names, as in P6 where "1 error" was followed by a second one after the first fix. Fix the first error, recompile, and trust only a silent compile followed by correct output.
Mini Challenge
Make your own set of three broken programs for a friend or classmate: three short files, each with one fault from this module (use a different fault each time, and a different message to print). Keep a separate answer sheet with the expected message, the line, and the fix. Test your own broken files yourself so the messages on your answer sheet are real, not remembered.
Check your work: each file fails in exactly the way your sheet says, every fix makes the program print the intended text, and your answer sheet uses message texts copied from the compiler.
Summary & Next Lesson
Key takeaways
- The fix loop is: compile, read the first message, fix one thing, recompile.
- The five faults map to the messages:
';' expected, a name error (package ... does not existorcannot find symbol),reached end of file while parsing, a launch error for the wrongmain, andunclosed string literal. - A wrong
mainline compiles but fails at launch with an error fromjava. - "1 error" is not proof of one mistake. Fix, recompile, repeat until silent, then check the output.
- Keeping a log of messages and fixes builds your own field guide.
Next lesson
This was the last lesson in the module. Next is the lab BEG-008-LAB1, "Business card", where you print a formatted business card, add comments, and fix five provided broken programs using only the compiler messages.
Self-check
- Which fault is only visible when you run the program?
- Why recompile after each fix?
- What does the caret in a
javacmessage point to? - Which command printed
Main method not found? - After fixing the first error, the compiler shows a new one. Did you do something wrong?
أظهر الإجابات
- The wrong
mainline. - Because one fix may reveal another error that was hidden, and you want to know which change did what.
- The place where the compiler noticed the problem, which is sometimes just after the real mistake.
java, the launcher, notjavac.- No. The compiler could read further and found the next problem.
References
- Oracle,
javaccommand reference, JDK 21 andjavacommand reference, JDK 21. They describe compiling a source file to a class file and launching a class'smainmethod. - Oracle, The Java Language Specification, Java SE 21, section 12.1.4. It says
mainmust bepublic,static,void, and take aStringarray. - All messages shown were produced by compiling and running these exact files with JDK 21 on Windows, and the same checks were run for the Q-programs. Other JDK versions may word messages and report errors differently. The "grammar errors first" behaviour is observed, not documented. Not verified: the wording of the launch message for a non-static
mainin other JDK versions, and the IntelliJ details, which come from general experience.
التطبيق
طبّق هذا الدرس بمختبر الوحدة وتمارينها واختبارها.
تعليم الدرس كمكتمل اختياري ويمكنك التراجع عنه في أي وقت. يبقى تقدمك محفوظًا في هذا المتصفح.