Null/technische Ausnahme und verteiltes Logging
Fehlerkontext ist technisch oder wird durch Rückgabewerte verschleiert.
Vollständiger Legacy-Modern-Vergleich aller Java-Klassen, Tests, Maven-POMs und relevanten Ressourcen dieses Moduls. Jede Datei ist genau einmal einer fachlich passenden Vergleichsgruppe zugeordnet.
Fehlerkontext ist technisch oder wird durch Rückgabewerte verschleiert.
Eine benannte fachliche Exception trägt den fehlenden Schlüssel und wird zentral geloggt.
Die Ähnlichkeit ist eine technische Orientierung auf normalisiertem Quelltext. Sie ersetzt keine fachliche Bewertung.
| Vergleichsgruppe | Legacy-Dateien | Modern-Dateien | Legacy-Zeilen | Modern-Zeilen | Ähnlichkeit |
|---|---|---|---|---|---|
| Build-Konfiguration | 1 | 1 | 34 | 34 | 100% |
| Lookup, Exception und Test | 2 | 3 | 27 | 34 | 47% |
Das Pair-POM bindet die Legacy- und Modern-Submodule zusammen und gehört deshalb ebenfalls zur vollständigen Codeabdeckung.
Logging- und Testabhängigkeiten werden verglichen.
| Legacy-Dateien | Modern-Dateien | Einordnung |
|---|---|---|
| pom.xml | pom.xml | Direktvergleich Semantische Ähnlichkeit: 100% |
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>at.aydin.academy</groupId>
<artifactId>18exceptionlogging-pair</artifactId>
<version>1.0.0</version>
<relativePath>../pom.xml</relativePath>
</parent>
<artifactId>exception-logging-legacy</artifactId>
<packaging>jar</packaging>
<name>Exception Logging Legacy</name>
<dependencies>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
</plugin>
</plugins>
</build>
</project><?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>at.aydin.academy</groupId>
<artifactId>18exceptionlogging-pair</artifactId>
<version>1.0.0</version>
<relativePath>../pom.xml</relativePath>
</parent>
<artifactId>exception-logging-modern</artifactId>
<packaging>jar</packaging>
<name>Exception Logging Modern</name>
<dependencies>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>Generische Fehlerbehandlung wird durch domänenspezifische Exception und strukturiertes Logging ersetzt.
| Legacy-Dateien | Modern-Dateien | Einordnung |
|---|---|---|
| LegacyCustomerLookup.java LegacyCustomerLookupTest.java | CustomerLookupService.java CustomerNotFoundException.java CustomerLookupServiceTest.java | Direktvergleich Semantische Ähnlichkeit: 47% |
package at.aydin.lab.errors.legacy;
// Design Pattern: Exception Shielding (Legacy-Antipattern-Variante) – fängt technische Fehler, verschluckt sie jedoch.
import java.util.*;
public final class LegacyCustomerLookup {
private final Map<Long, String> data = Map.of(1L, "Aydin");
public String find(long id) {
try {
return data.get(id).toUpperCase();
} catch (Exception ex) {
System.err.println(ex);
return null;
}
}
}package at.aydin.lab.errors.legacy;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;
class LegacyCustomerLookupTest {
@Test
void hidesFailureWithNull() {
assertNull(new LegacyCustomerLookup().find(99));
}
}package at.aydin.lab.errors.modern;
import java.util.*;
// Design Pattern: Exception Translator
// Zweck: Technische Abwesenheit wird in eine eindeutige fachliche Exception übersetzt.
public final class CustomerLookupService {
private static final System.Logger LOG = System.getLogger(CustomerLookupService.class.getName());
private final Map<Long, String> data = Map.of(1L, "Aydin");
public String find(long id) {
return Optional.ofNullable(data.get(id)).map(String::toUpperCase).orElseThrow(() -> {
LOG.log(System.Logger.Level.WARNING, "customerId={0} not found", id); return new CustomerNotFoundException(id);
});
}
}package at.aydin.lab.errors.modern;
public final class CustomerNotFoundException extends RuntimeException {
public CustomerNotFoundException(long id) {
super("Kunde nicht gefunden: " + id);
}
}package at.aydin.lab.errors.modern;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;
class CustomerLookupServiceTest {
@Test
void throwsDomainException() {
assertEquals("AYDIN", new CustomerLookupService().find(1));
assertThrows(CustomerNotFoundException.class, () -> new CustomerLookupService().find(99));
}
}