# Object Oriented Programming 2 — Stale course audit

- URL: https://getstale.tech/run/refactor_oop2_20260506T135257Z
- Target role: Backend Engineer
- Course focus: Object-Oriented Java Programming — Applied Apis And Gui
- Audit date: 2026-05-06T13:52:57Z
- Verified findings: 8
- Structured data: https://getstale.tech/run/refactor_oop2_20260506T135257Z.json

## Findings

### 1. Security risk (critical severity)

**Location:** Week 9 - Accessing DB ( Part 3 ).pdf page 6, Week 9 - Accessing DB ( Part 3 ).pdf page 24

**What the slide says:**

> private static final String PASSWORD = "deitel";

**Primary source:** https://cwe.mitre.org/data/definitions/798.html (verified)

> The product contains hard-coded credentials, such as a password or cryptographic key.

**What to learn instead:** Read credentials from environment variables, an external configuration file with restricted permissions, or a secrets manager (Vault, AWS Secrets Manager, etc.). Show students how to keep secrets out of source control from day one.

### 2. Misleading idea (high severity)

**Location:** Week 8 - Accessing DB ( Part 2 ).pdf page 20

**What the slide says:**

> Any local variable that will be used in an anonymous inner class must be declared final; otherwise, a compilation error occurs.

**Primary source:** https://docs.oracle.com/javase/specs/jls/se8/html/jls-8.html (verified)

> Any local variable, formal parameter, or exception parameter used but not declared in an inner class must either be declared final or be effectively final

**What to learn instead:** Update the wording to: "Any local variable used in an anonymous inner class must be either `final` or *effectively final* (Java 8+); attempting to reassign a captured local is a compile-time error."

### 3. Misleading idea (high severity)

**Location:** Week 10 - Files Streams and Object Serialization ( Part 1 ).pdf page 5

**What the slide says:**

> sequence of characters in which every character is two

**Primary source:** https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/lang/Character.html (verified)

> supplementary characters are represented as a pair of char values, the first from the high-surrogates range, (\uD800-\uDBFF), the second from the low-surrogates range (\uDC00-\uDFFF)

**What to learn instead:** Rewrite the bullet as: "Java's `char` is a 16-bit UTF-16 *code unit*. BMP characters (U+0000 to U+FFFF) fit in one `char`; supplementary characters (emoji and many CJK glyphs) are encoded as a surrogate pair — two `char`s, four bytes — so `String.length()` counts code units, not characters. Use `codePointAt`/`codePointCount` when you need the actual character count."

### 4. No longer works (medium severity)

**Location:** Week 2+3 - Exception Handling.pdf page 91

**What the slide says:**

> Run with Java Web Start

**Primary source:** https://docs.oracle.com/en/java/javase/17/migrate/removed-tools-and-components.html (verified)

> Java applet and Web Start functionality, including the Java plug-in, the Java Applet Viewer, Java Control Panel, and Java Web Start, along with javaws tool, have been removed in JDK 11.

**What to learn instead:** Drop the screenshot and the assertion-debugging instructions that depend on Web Start. For local debugging, point students at the IDE's standard Run/Debug configuration; for deployment, mention `jlink`/`jpackage` or third-party reimplementations such as OpenWebStart if Web Start compatibility is genuinely needed.

### 5. Deprecated (medium severity)

**Location:** Week 2+3 - Exception Handling.pdf page 57

**What the slide says:**

> Finalize is used to perform clean up processing just before object is garbage collected.

**Primary source:** https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/lang/Object.html (verified)

> Deprecated. The finalization mechanism is inherently problematic.

**What to learn instead:** Keep the `final`/`finally` half of the comparison, and replace the `finalize` row with `try-with-resources` + `AutoCloseable`/`Cleaner` as the modern way to release resources. Mention `Object.finalize()` only as a historical/deprecated artifact.

### 6. Deprecated (medium severity)

**Location:** Week 6 - GUI Components ( Part 3 ).pdf page 11

**What the slide says:**

> Method getModifiers determines whether any modifier keys (such as Shift, Alt and Ctrl) were pressed when the key event occurred.

**Primary source:** https://docs.oracle.com/en/java/javase/17/docs/api/java.desktop/java/awt/event/InputEvent.html (verified)

> It is recommended that extended modifier keys and getModifiersEx() be used instead

**What to learn instead:** Teach `getModifiersEx()` with the `*_DOWN_MASK` constants (`SHIFT_DOWN_MASK`, `CTRL_DOWN_MASK`, etc.) and `KeyEvent.getModifiersExText(int)` for the human-readable string. Show the `(event.getModifiersEx() & (onmask | offmask)) == onmask` idiom from the Oracle docs.

### 7. No longer works (medium severity)

**Location:** Week 7 - Accessing DB ( Part 1 ).pdf page 11

**What the slide says:**

> see the Java DB Developer's Guide at

**Primary source:** https://docs.oracle.com/en/java/javase/17/migrate/removed-tools-and-components.html (verified)

> JavaDB, which was a rebranding of Apache Derby, is no longer included in the JDK.

**What to learn instead:** Drop the "Java DB" branding and the Oracle javadb URL. If Derby is still desired, install Apache Derby externally (https://db.apache.org/derby/derby_downloads.html); otherwise switch the lab to a more current teaching DB (H2, SQLite, or PostgreSQL).

### 8. Deprecated (low severity)

**Location:** Week 2+3 - Exception Handling.pdf page 79

**What the slide says:**

> public Image getImage(URL url, String name) {

**Primary source:** https://openjdk.org/jeps/289 (verified)

> Add the @Deprecated(since="9") annotation to the following classes:

**What to learn instead:** Replace the Javadoc example with code from a non-deprecated API (e.g. a `java.util.List` method, an `HttpClient` example, or a custom domain class). The Javadoc tags being demonstrated (@param, @return, @link, @see) are independent of the Applet API.

## Market fit

This is a Java desktop-applications course (Swing GUI + Apache Derby JDBC + object serialization) whose domain barely overlaps backend hiring — within its own depth bound the only defensible extensions are swapping the JDBC labs from Derby to PostgreSQL and lifting the existing assert-statement section into a JUnit @Test introduction; the rest of the modern backend stack (Docker, AWS, REST/HTTP, microservices, Kubernetes, Redis, Kafka, OAuth/JWT) has zero partial coverage to extend and is therefore out of scope for this course.

### PostgreSQL as the JDBC target database (vs. Apache Derby / Java DB) (critical)

The JDBC unit teaches database connectivity but pins every concrete example to Apache Derby. PostgreSQL is named only twice — once in the RDBMS list ('PostgreSQL' alongside Oracle/MySQL/DB2 on Week 7 Page 4) and once as a URL-format row ('PostgreSQL jdbc:postgresql://hostname:portNumber/databaseName' in Fig. 24.24, Week 8 Page 34). Every code sample uses 'jdbc:derby://localhost:1527/books' (Week 8 Page 5) and 'jdbc:derby:books' (Week 9 Page 6). Extending the existing JDBC labs to point at a Postgres instance — same Connection/Statement/PreparedStatement API the course already teaches, just a different driver/URL — would close the gap while staying inside the standard-library JDBC depth bound. The course already lists Postgres in the URL table, so the partial-coverage anchor is explicit.

### Unit testing with JUnit (@Test, assertEquals) (high)

Section 11.11 of Week 2+3 already teaches Java's built-in 'assert' statement: 'Assertions help ensure a program's validity by catching potential bugs and identifying possible logic errors during development' and shows AssertTest.java with 'assert (number >= 0 && number <= 10) : "bad number: " + number;' (Week 2+3 Pages 86-90). The intent — programmatically validating expected behaviour during development — is the same intent as a unit test. The course presently stops at the language-level assert keyword run via 'java -ea'. Extending this section to introduce a JUnit @Test method with assertEquals/assertThrows applied to the existing Employee/Account classes the course already builds would lift the existing assertions material to the standard form the market expects, without crossing into build/deployment tooling. Anchor slide for partial coverage: 'I 1.11 Assertions' (Week 2+3 Page 3) and 'Assertions help ensure a program's validity by catching potential bugs and identifying possible logic errors during development' (Week 2+3 Page 86).

## Recommended topics

Only two prescriptions survive the depth bound and the partial-coverage rule: (1) re-pointing the JDBC labs from Apache Derby to PostgreSQL with env-var credentials and PreparedStatement-from-day-one (0.917 of postings), and (2) lifting the existing Java 'assert' section into a JUnit @Test introduction (0.833 of postings). Together they touch the two highest-frequency demands the course has any partial-coverage anchor for.

### #1 Re-point the JDBC labs from Apache Derby to PostgreSQL, with credentials read from environment variables and PreparedStatement used from the first user-input query (~6h to learn)

Swap the Derby labs for PostgreSQL using the same JDBC API the course already teaches — and bake in env-var credentials and PreparedStatement from the first query, not bolted on later.

Keywords: postgresql, jdbc, postgresql jdbc driver, preparedstatement, environment-variable credentials

Where it fits: Week 8 - Accessing DB Part 2 · Week 8 is where the course first turns the JDBC API into a runnable lab (DATABASE_URL, Connection, Statement, ResultSet). Fig. 24.24 on Week 8 Page 34 already lists 'PostgreSQL jdbc:postgresql://hostname:portNumber/databaseName' alongside the Derby URL — the partial-coverage anchor is explicit. The extension is to pivot every concrete code sample from 'jdbc:derby://localhost:1527/books' to a PostgreSQL URL using the same Connection/Statement/PreparedStatement surface. Two Auditor-flagged patterns sit in this same unit and must be replaced, not extended: (a) the hardcoded 'private static final String PASSWORD = "deitel";' on Week 9 pages 6 and 24 must be replaced with credentials read from environment variables (or a properties file outside source control) on the very first PostgreSQL example, per the Auditor's suggested_replacement; (b) the string-concatenated 'SELECT * FROM AUTHORS WHERE FIRSTNAME LIKE ...' on Week 8 page 9 must be replaced with a PreparedStatement using '?' placeholders and setString — not deferred to Week 9. Week 7 Page 11's dead 'Java DB Developer's Guide' link should also be dropped in favor of the PostgreSQL JDBC driver docs.

### #2 Lift the existing Java 'assert' / Section 11.11 Assertions material into a JUnit 5 @Test introduction (assertEquals, assertThrows) applied to the course's existing Account/Employee classes (~6h to learn)

Promote the existing 'assert' lecture into a one-class JUnit @Test walkthrough on the Account/Employee classes the course already builds — same intent, the form the market actually writes.

Keywords: junit, junit 5, @test, assertequals, assertthrows, unit testing

Where it fits: Week 2+3 - Exception Handling · Section 11.11 of Week 2+3 (Pages 86–90) already teaches the language-level 'assert' statement with the explicit pedagogical framing that 'Assertions help ensure a program's validity by catching potential bugs and identifying possible logic errors during development' and shows AssertTest.java run via 'java -ea'. That is the same intent as a unit test, just stuck at the keyword-and-VM-flag level. The natural extension — well within standard-library/applied-API depth — is to introduce a single JUnit 5 test class with @Test methods that call assertEquals on, e.g., the deposit/withdraw behaviour of the Account class and assertThrows on the user-defined exceptions the course already builds. This stays inside the course's hands-on standard-library scope (JUnit ships as a single jar on the classpath) and does not push into Maven/Gradle/CI build tooling, which the depth bound excludes. The Auditor-flagged items in this unit (Web Start screenshot on page 91, the Applet getImage Javadoc example on page 79, the finalize() row on page 57) are not used as prerequisites here and are not extended by this prescription.

---
Produced by Stale (https://getstale.tech). Request a course audit: https://getstale.tech/request-audit
