Block 11 · Entwicklungsumgebung & Werkzeuge – Lösungen

Lösungssatz zu 11_Werkzeuge.html · Musterlösungen mit Bewertungshinweisen; zwei lauffähige Java-Beispiele im Ordner java\11_Werkzeuge\ (Start mit java Aufgabe_WZ_04_2.java bzw. java Aufgabe_WZ_05_3.java)
Hinweise zur Bewertung Wie in den IHK-Lösungshinweisen gilt: Andere sach- und fachgerechte Antworten werden ebenfalls voll bewertet. Bei „nennen“ genügt ein Stichwort, bei „beschreiben“ und „erläutern“ wird ein ganzer Satz mit Begründung bzw. Wirkung erwartet, bei „bewerten“ und „begründen“ eine Entscheidung mit fachlicher Begründung – möglichst mit Bezug auf die Situation (MonteurPlus). Wo mehrere Lösungen aufgeführt sind, reicht jeweils die geforderte Anzahl.

Lösungen

WZ-01 · Versionsverwaltung (Git)

Aufgabe WZ-01.1 · 5 Punkte

a) Zentral vs. verteilt (2 P)

Bei einer zentralen Versionsverwaltung (z. B. Subversion) gibt es nur ein Repository mit der gesamten Historie auf einem Server. Die Entwickler haben lediglich eine Arbeitskopie; Commits, Historie und Vergleiche erfordern eine Verbindung zum Server. Bei einer verteilten Versionsverwaltung (z. B. Git) besitzt jeder Entwickler einen vollständigen Klon des Repositorys einschließlich Historie. Commits erfolgen lokal (auch offline); Änderungen werden per push/pull mit anderen Repositories, meist einem gemeinsamen Remote-Repository, ausgetauscht.

b) Begriffe (3 P)

BegriffErläuterung (Beispiel)
RepositoryDatenbank/Ablage eines Projekts mit allen Dateien und ihrer vollständigen Versionshistorie (lokal im Ordner .git oder als Remote-Repository auf dem GitLab-Server).
CommitGespeicherter Stand (Schnappschuss) der vorgemerkten Änderungen mit eindeutiger ID, Autor, Zeitpunkt, Nachricht und Verweis auf den Vorgänger.
BranchEigenständiger Entwicklungszweig, technisch ein beweglicher Zeiger auf den letzten Commit; ermöglicht paralleles Arbeiten, ohne den Hauptzweig zu verändern.
MergeZusammenführen der Änderungen eines Branches in einen anderen (Fast-Forward oder Merge-Commit; ggf. mit Konfliktauflösung).
PushÜbertragen lokaler Commits in ein entferntes Repository (Remote), damit andere sie erhalten.
TagFester, unveränderlicher Name für einen bestimmten Commit, meist zur Kennzeichnung eines Releases (z. B. v1.3.0).
Bewertung: a) je Variante mit Kernmerkmal (Repository nur auf dem Server vs. vollständige Kopie bei jedem Entwickler) 1 P. b) je richtig erläutertem Begriff 0,5 P.
Aufgabe WZ-01.2 · 10 Punkte

a) Commit-Graph nach Befehl (10) (4 P)

… ältere Commits C 7d2e4b1 F1 F2 N M feature/MP-130-fotos HEAD → main origin/main v1.3.0 Zeit →
Abb. L-1: Commit-Graph nach Befehl (10): M hat die Vorgänger N und F2; main, HEAD, origin/main und Tag v1.3.0 zeigen auf M

Die Reihenfolge von N gegenüber F1/F2 auf der Zeitachse ist beliebig (N entstand parallel). origin/main steht nach Befehl (9) ebenfalls auf M; die Angabe ist optional.

b) Fast-Forward? (2 P)

c) Merge-Konflikt (3 P)

Ursache: Seit der Abzweigung von feature/MP-131-anfahrt wurde dieselbe Zeile in anfahrtspauschale() auf beiden Seiten unterschiedlich geändert: auf main (HEAD) wurden die Pauschalen auf 89/39 € erhöht, im Feature-Branch wurde die Berechnung um einen Entfernungsanteil (0,50 €/km) erweitert. Git kann nicht entscheiden, welche Fassung gelten soll, und bricht den automatischen Merge ab.

Auflösen:

  1. Mit git status die betroffene Datei ermitteln und im Editor/IDE-Merge-Werkzeug öffnen.
  2. Fachlich klären, welcher Inhalt richtig ist (Tickets MP-131 und Preisänderung, ggf. Rücksprache mit dem Kollegen bzw. Fachbereich). Hier ist vermutlich eine Kombination gewünscht:
    return a.isNotdienst() ? 89.00 : 39.00 + 0.50 * a.getEntfernungKm();
  3. Konfliktmarker <<<<<<<, =======, >>>>>>> entfernen.
  4. Kompilieren und Tests ausführen.
  5. Datei mit git add als gelöst markieren, Merge mit git commit abschließen, danach git push. (Alternative bei Unklarheit: git merge --abort und erst klären.)

d) fetch (1 P)

git fetch (z. B. danach git log main..origin/main): lädt die neuen Commits vom Remote und aktualisiert nur den Remote-Zeiger origin/main; lokaler Branch und Arbeitsverzeichnis bleiben unverändert. git pull führt zusätzlich einen Merge (bzw. Rebase) in den aktuellen Branch aus und verändert ihn.

Bewertung: a) F1/F2 auf eigenem Zweig ab C 1 P, N auf main 1 P, M mit zwei Vorgängern 1 P, Zeiger main/HEAD, Feature-Branch und Tag richtig 1 P (Pfeile in Zeitrichtung statt zum Vorgänger: keine Abzüge, wenn eindeutig). b) je Befehl Aussage mit Begründung 1 P. c) Ursache 1 P, Auflösung mit fachlicher Entscheidung, Marker entfernen, add/commit 2 P. d) Befehl und Abgrenzung 1 P.

Erklärung / typische Fehler: Häufig wird bei (6) ein Merge-Commit gezeichnet – ohne eigene lokale Commits ist ein Pull aber immer ein Fast-Forward. Ebenso falsch: M nur mit einer Linie zu F2 verbinden; ein Merge-Commit hat immer zwei Vorgänger. Den Konflikt einfach durch „eine Seite übernehmen“ zu lösen, ohne die Fachlichkeit zu klären, verliert eine der beiden Änderungen.

Aufgabe WZ-01.3 · 18 Punkte

a) Stellungnahme zu Punkt 1 (4 P)

Ich stimme der Umstellung auf Git zu. Begründung (zwei der folgenden Argumente):

b) Punkte 2–4 (6 P)

PunktProblemVerbesserungsvorschlag
2Unfertige und ungetestete Änderungen landen sofort im gemeinsamen Stand; main ist häufig nicht lauffähig und nicht auslieferbar (vgl. Störung vom 03.07.2026). Acht Personen auf einem Branch erzeugen ständig Konflikte; vor der Integration gibt es keine Prüfung durch Review oder Pipeline.Für jedes Ticket ein eigener, kurzlebiger Feature-Branch; Übernahme in main nur per Merge Request nach erfolgreicher Pipeline. main als geschützten Branch einrichten (kein direkter Push).
3Die Testerin prüft fachliches Verhalten am Ende, sieht aber den Code nicht: Wartbarkeit, Verständlichkeit, Sicherheitslücken und Verstöße gegen Konventionen bleiben unentdeckt; Fehler werden spät und teuer gefunden; Wissen über Codeteile bleibt bei einer Person.Code-Review im Merge Request durch mindestens eine weitere Person (Vier-Augen-Prinzip), kleine Merge Requests, damit Reviews schnell gehen; ergänzend automatische Prüfungen (statische Analyse, Tests) in der Pipeline. Tests der Testerin bleiben zusätzlich bestehen.
4target/ enthält erzeugte Build-Dateien und .idea/ persönliche IDE-Einstellungen → unnötige Konflikte, großes Repository, veraltete Artefakte. Die application-local.properties mit Zugangsdaten wäre für alle Leser des Repositorys sichtbar und bliebe dauerhaft in der Historie (Sicherheitsrisiko, Vertraulichkeit)..gitignore mit target/, .idea/ und application-local.properties anlegen; nur eine Vorlage ohne Passwörter (z. B. application-local.properties.example) versionieren; Zugangsdaten über Umgebungsvariablen bzw. CI/CD-Variablen bereitstellen; bereits eingecheckte Passwörter ändern.

c) Branching-Strategie (4 P)

Feature-Branch-Workflow mit Merge Requests (GitLab-Flow). Ablauf für ein Ticket, z. B. MP-142:

  1. Aktuellen Stand holen: git switch main, git pull.
  2. Branch anlegen: git switch -c feature/MP-142-materialliste.
  3. In kleinen Schritten committen (aussagekräftige Nachrichten mit Ticketnummer) und den Branch regelmäßig pushen.
  4. Merge Request nach main öffnen → Pipeline läuft automatisch (Build, Tests, Analyse).
  5. Code-Review durch eine Kollegin/einen Kollegen, Anmerkungen einarbeiten.
  6. Bei grüner Pipeline und Freigabe: Merge in den geschützten main, Feature-Branch löschen; das Deployment erfolgt über die Pipeline.

Begründung: Für ein Team von acht Personen, das ein SaaS-Produkt mit nur einer aktuellen Version kontinuierlich ausliefert, ist dieser Workflow einfach und passt zur Pipeline. Git-Flow (develop/release/hotfix-Branches) wäre unnötig aufwendig. Trunk-based Development mit sehr kurzlebigen Branches ist ebenfalls vertretbar, setzt aber sehr gute Testabdeckung voraus.

d) Punkt 6 (2 P)

ZIP-Kopien sind nicht mit der Historie verknüpft: Man weiß nicht, welcher Commit genau ausgeliefert wurde; Namen wie „final2“ sind uneindeutig; das Netzlaufwerk soll ohnehin schreibgeschützt werden. Stattdessen den Release-Commit mit einem Tag markieren, z. B. git tag -a v1.3.0 -m "Release 1.3.0" (Versionsnummer nach SemVer), und den Tag pushen; das Artefakt erzeugt die Pipeline (ggf. als GitLab-Release).

e) Punkt 5 (2 P)

Das Log zeigt Nachrichten wie fix, asdf und Zwischenstand Freitag: Ohne Blick in den Code ist nicht erkennbar, was und warum geändert wurde; Fehlersuche, Reviews und Release Notes werden erschwert. Commit-Nachrichten sollten verpflichtend sein (Ticketnummer + kurze Beschreibung). Vorschlag für a41c9e2:
MP-109: Fehlende Kundenadresse beim Speichern eines Auftrags abfangen
(optional zweiter Absatz: „Statt einer NullPointerException wird jetzt die Meldung ‚Kundenadresse fehlt‘ ausgegeben.“)

Bewertung: a) Zustimmung mit zwei Argumenten, je Argument 2 P (genannt 1 P, auf die Situation bezogen erläutert 1 P); Ablehnung ohne tragfähige Begründung 0 P. b) je Punkt Problem 1 P und Verbesserung 1 P. c) Strategie benannt 1 P, Ablauf (Branch, Merge Request/Review, Pipeline, Merge) 3 P; Git-Flow oder Trunk-based mit schlüssiger Begründung ebenfalls volle Punktzahl. d) Bewertung 1 P, Tag 1 P. e) Bewertung 1 P, sinnvolle Nachricht 1 P.

Erklärung: „Bewerten“ heißt hier: Problem benennen und eine konkrete Verbesserung vorschlagen. Besonders wichtig ist Punkt 4 – Zugangsdaten im Repository sind ein klassischer Sicherheitsfehler, der in Prüfungen gern mit IT-Sicherheit verknüpft wird.

WZ-02 · CI/CD & Deployment

Aufgabe WZ-02.1 · 5 Punkte

a) Abgrenzung (3 P)

b) Aufgaben eines Build-Werkzeugs (2 P)

Zwei davon: Abhängigkeiten (inkl. transitiver) auflösen und herunterladen · Quellcode kompilieren · automatische Tests ausführen · Artefakte packen (JAR/WAR) · Versionen in ein Repository veröffentlichen · Dokumentation/Berichte erzeugen · einheitlicher, reproduzierbarer Build-Ablauf (Lebenszyklus) auf jedem Rechner und dem CI-Server.

Bewertung: a) je Begriff 1 P; der entscheidende Unterschied Delivery/Deployment (manuelle Freigabe ja/nein) muss erkennbar sein. b) je Aufgabe 1 P.
Aufgabe WZ-02.2 · 10 Punkte

a) Ablauf der Pipeline für einen Push auf main (4 P)

Stage build Stage test Stage analyse Stage package Stage staging Stage production buildmvn compile unit-testsmvn test parallel integration-testsmvn verify, Test-DB code-analyseCheckstyle, SpotBugs packageImage bauen, pushen automatisch package bis production nur bei Branch main (rules) deploy-staging./deploy.sh staging Freigabe per Klick(when: manual) deploy-production./deploy.sh production Fehlerfall: Schlägt ein Job fehl, laufen die übrigen Jobs derselben Stage zu Ende, die folgenden Stages starten nicht. Die Pipeline ist „fehlgeschlagen“, das Team wird benachrichtigt – nichts wird ausgeliefert.
Abb. L-2: Ablauf der Server-Pipeline aus Anlage 5 (Notation angelehnt an das UML-Aktivitätsdiagramm)

Eine einfachere Darstellung als Kette von Kästen (Stages nebeneinander, Jobs einer Stage untereinander) ist ebenso richtig.

b) Delivery oder Deployment? (2 P)

Es handelt sich um Continuous Delivery: Bis zur Staging-Umgebung läuft alles automatisch, der Job deploy-production hat aber when: manual und startet erst, wenn eine berechtigte Person ihn auslöst. Bei Continuous Deployment würde auch die Produktion ohne manuellen Schritt aktualisiert.

c) Push auf einen Feature-Branch (2 P)

Es laufen nur build, unit-tests, integration-tests und code-analyse; package, deploy-staging und deploy-production sind per rules auf main beschränkt. Schlägt unit-tests fehl, läuft integration-tests (gleiche Stage) noch zu Ende, die Stage analyse startet nicht mehr, die Pipeline wird als fehlgeschlagen markiert und die Entwicklerin benachrichtigt. Sie muss den Fehler beheben und erneut pushen; ein Merge in main sollte bei roter Pipeline gesperrt sein.

d) Staging-Umgebung (2 P)

Die Staging-Umgebung ist eine produktionsnahe Kopie (gleiches Container-Image, gleiche Java- und PostgreSQL-Version, ähnliche Konfiguration, anonymisierte Albers-Daten). Dort wird jede neue Version vor der Produktion installiert: Installation und Datenbankmigration werden geprüft, die Testerin und ggf. Disponenten von Albers nehmen die Version ab. Fehler wie ein fehlendes Datenbankskript (Störung vom 19.06.) fallen auf, ohne dass Monteure und Disponenten betroffen sind.

Bewertung: a) Reihenfolge der Stages 1 P, parallele Test-Jobs 1 P, manueller Schritt vor Produktion 1 P, Fehlerfall bzw. Bedingung „nur main“ 1 P. b) Entscheidung 1 P, Begründung mit when: manual 1 P. c) Jobs 1 P, Verhalten bei Fehler 1 P. d) Zweck (produktionsnaher Test/Abnahme vor Produktion) 1 P, Bezug zum Projekt 1 P.
Aufgabe WZ-02.3 · 18 Punkte

a) Automatisierte Kompilierung und Bereitstellung (3 P)

Der Quellcode liegt ausschließlich in der Versionsverwaltung (Git). Ein CI/CD-Server (z. B. GitLab CI) startet bei jedem Push bzw. Merge auf main automatisch eine Pipeline, die in einer festgelegten Umgebung (Container-Image mit Java 21) mit Maven kompiliert, alle automatischen Tests und die statische Analyse ausführt und daraus ein versioniertes Artefakt (JAR bzw. Container-Image) erzeugt und in einer Registry ablegt. Ein Skript installiert dieses Artefakt automatisch auf der Staging-Umgebung und nach Freigabe auf dem Produktivserver, spielt Datenbankänderungen per Migrationswerkzeug ein, startet den Dienst neu und prüft per Health-Check, ob er läuft. Jeder Lauf wird protokolliert, bei Fehlern wird das Team benachrichtigt.

b) Zwei Störungen und Vorteile (4 P)

StörungSo hätte die Automatisierung sie verhindertVorteil
05.06.Gebaut wird immer im selben definierten Image (Java 21), ausgeliefert wird ein Image mit passender Laufzeit – Versionsunterschiede zwischen Admin-PC und Server gibt es nicht mehr.einheitliche, reproduzierbare Umgebung
19.06.Migrationsskripte liegen versioniert im Repository und werden bei jedem Deployment automatisch eingespielt (z. B. mit DbMigrate/Flyway); kein Versand per E-Mail, nichts wird vergessen.vollständig und fehlerarm, keine vergessenen Schritte
03.07.Ausgeliefert wird nur, was in main gemergt wurde und alle Tests bestanden hat; unfertige Stände auf Feature-Branches gelangen nicht in die Produktion.Qualitätssicherung vor jeder Auslieferung
17.07.Der Ablauf steckt im Skript; jede berechtigte Person kann per Klick ausliefern, der Neustart ist Teil des Skripts.Unabhängigkeit von Einzelpersonen, schnellere Bereitstellung

c) Schwachstellen im Pipeline-Entwurf (6 P)

Nr.SchwachstelleVerbesserung
1Keystore-Passwort und Play-Store-Zugang stehen im Klartext in der Datei – lesbar für alle 45 Mitarbeitenden und dauerhaft in der Git-Historie. Wer sie kennt, kann gefälschte App-Updates signieren und veröffentlichen.Als geschützte, maskierte CI/CD-Variablen (nur für geschützte Branches) bzw. in einem Secret-Speicher hinterlegen; die bereits offengelegten Zugangsdaten sofort ändern.
2allow_failure: true bei den Unit-Tests: Schlagen Tests fehl, wird trotzdem veröffentlicht – die Tests sind wirkungslos.allow_failure entfernen; fehlschlagende Tests müssen die Pipeline stoppen; Tests reparieren statt ignorieren.
3deploy-playstore hat keine rules und keine Freigabe: Jeder Push auf jeden Branch (auch unfertige Feature-Branches) veröffentlicht sofort für alle Nutzer im Produktions-Track; keine Test-/Staging-Stufe.Nur für main bzw. Release-Tags ausführen, zunächst in einen internen Test-Track (Testgruppe bei Albers) veröffentlichen, Produktion per when: manual freigeben, ggf. gestaffelter Rollout.
4Keine statische Analyse (z. B. Android Lint) und keine Instrumentierungs-/UI-Tests.Stage analyse mit ./gradlew lint ergänzen.
5Die App wird im Deploy-Job neu gebaut statt das geprüfte Ergebnis aus build-app zu verwenden.Artefakt aus build-app per artifacts weitergeben und genau dieses veröffentlichen („build once, deploy many“).

d) Container (3 P)

Das Container-Image enthält die Anwendung zusammen mit ihrer Laufzeitumgebung (Java 21) und allen Bibliotheken. Die Pipeline baut das Image einmal; genau dieses Image läuft unverändert in Staging und Produktion. Welche Java-Version auf dem Server installiert ist, spielt keine Rolle mehr – der Server benötigt nur eine Container-Laufzeit. Ein UnsupportedClassVersionError durch Java 21 vs. Java 17 kann dadurch nicht mehr auftreten.

Unterschied zur VM (einer genügt): Container teilen sich den Kernel des Host-Betriebssystems und enthalten kein eigenes Betriebssystem → klein (MB) und in Sekunden gestartet; eine virtuelle Maschine virtualisiert Hardware und enthält ein vollständiges Gast-Betriebssystem → größer (GB), langsamer im Start, dafür stärker isoliert.

e) DevOps (2 P)

DevOps (Development + Operations) heißt, dass Entwicklung und Betrieb nicht als getrennte Abteilungen arbeiten, die Software „über den Zaun werfen“, sondern als ein Team gemeinsam Verantwortung für Entwicklung, Auslieferung und Betrieb tragen. Dazu gehören weitgehende Automatisierung (CI/CD, Infrastruktur als Code), kleine und häufige Releases, kurze Feedbackschleifen sowie Überwachung im Betrieb (Monitoring, Logging), deren Ergebnisse direkt in die Entwicklung zurückfließen – z. B. bindet das Team Herrn Okafor früh in Planung und Pipeline ein, und Entwickler sehen Fehlermeldungen aus der Produktion selbst.

Bewertung: a) Versionsverwaltung als Quelle/Auslöser 1 P, automatischer Build und Test 1 P, automatisches Deployment per Skript 1 P. b) je Störung Erläuterung 1 P, Vorteil 1 P. c) je Schwachstelle 1 P, je passender Verbesserung 1 P (drei von fünf). d) Wirkung des Containers auf die Störung 2 P, Unterschied zur VM 1 P. e) gemeinsame Verantwortung Dev/Ops 1 P, Automatisierung/Feedback 1 P.

Erklärung: In W22 gab es für die Umsetzung nur 2 P – dort genügten Stichworte wie „CI/CD-Pipeline: bei jedem Commit automatisch bauen, testen und auf den Server verteilen“. Bei den Vorteilen immer auf das konkrete Problem (hier Verfügbarkeit) eingehen.

WZ-03 · Softwarearchitektur

Aufgabe WZ-03.1 · 5 Punkte

a) Drei Schichten (3 P)

SchichtAufgabe (eine genügt)
PräsentationsschichtDaten für den Benutzer darstellen und Eingaben entgegennehmen (Web-Disposition im Browser, Monteur-App); einfache Eingabeprüfung; Anfragen an die Logikschicht senden.
Logikschicht (Anwendungs-/Geschäftslogik)Verarbeitung nach den Geschäftsregeln: Aufträge planen und zuweisen, Fahrzeiten berechnen, Berechtigungen und Vollständigkeit prüfen, Arbeitsberichte erzeugen (Anwendungsserver).
DatenhaltungsschichtDaten dauerhaft und konsistent speichern, lesen, ändern und löschen (PostgreSQL-Datenbank).

b) Thin Client und Fat Client (2 P)

Ein Thin Client übernimmt nur Darstellung und Eingabe; Logik und Daten liegen auf dem Server, ohne Verbindung ist er nicht nutzbar. Ein Fat Client enthält selbst einen großen Teil der Logik und häufig eigene Daten und kann daher auch offline arbeiten. Die Web-Disposition ist ein Thin Client (der Server erzeugt die Seiten, der Browser zeigt sie nur an); die Monteur-App ist ein Fat Client (lokale SQLite-Datenbank, Offline-Logik, späterer Datenabgleich).

Bewertung: a) je Schicht mit passender Aufgabe 1 P. b) Unterscheidung 1 P, beide Zuordnungen 1 P (je 0,5 P). Die Plantafel macht die Web-Disposition stellenweise „dicker“ – wer das erwähnt, liegt richtig.
Aufgabe WZ-03.2 · 10 Punkte

a) Zuordnung (3 P)

BestandteilRolleBegründung
auftragsliste.htmlViewstellt die Auftragsliste dar
auftragsliste.cssViewGestaltung der Darstellung
AuftragControllerControllernimmt die Anfrage entgegen, ruft das Model auf, wählt die View
AuftragServiceModelGeschäftslogik (filtern, sortieren, Überfälligkeit)
AuftragModelfachliche Daten
AuftragRepositoryModelDatenzugriff (Persistenz) des Models

b) Zusammenarbeit (4 P)

Browser (Disponentin) Controller AuftragController Model AuftragService filtern, sortieren AuftragRepository Datenzugriff PostgreSQL Auftrag Datenobjekte 3 lesen SQL View auftragsliste.html + .css 1 GET /auftraege?status=OFFEN &niederlassung=Kassel 2 findeAuftraege(…) 4 List<Auftrag> 5 Liste an Template übergeben 6 HTML-Seite
Abb. L-3: MVC in der Auftragsübersicht – nummerierte Schritte beim Aufruf der offenen Aufträge in Kassel
  1. Der Browser sendet die Anfrage GET /auftraege?status=OFFEN&niederlassung=Kassel an den AuftragController.
  2. Der Controller ruft den AuftragService (Model) mit den Filterwerten auf.
  3. Der Service lässt die Aufträge über das AuftragRepository per SQL aus der Datenbank lesen, filtert und sortiert sie.
  4. Das Model liefert eine Liste von Auftrag-Objekten an den Controller zurück.
  5. Der Controller übergibt die Liste an die View auftragsliste.html.
  6. Die View erzeugt die HTML-Seite (mit CSS gestaltet), die an den Browser zurückgeht.

c) MVC und 3-Schichten-Architektur (3 P)

Beide schließen sich nicht aus, sie betrachten unterschiedliche Ebenen. Die 3-Schichten-Architektur gliedert das gesamte System in Präsentation, Logik und Datenhaltung (auch über mehrere Rechner). MVC ist ein Muster für den Aufbau der Benutzeroberfläche einer Anwendung. Bei der Auftragsübersicht gehören View (auftragsliste.html, CSS) und AuftragController zur Präsentationsschicht – auch wenn das HTML auf dem Server erzeugt wird. Das Model verteilt sich auf die Logikschicht (AuftragService, Auftrag) und den Zugriff auf die Datenhaltungsschicht (AuftragRepository → PostgreSQL). Dieselbe Logikschicht wird außerdem von der REST-API für die App genutzt – ohne MVC-Views.

Bewertung: a) je Bestandteil 0,5 P; AuftragRepository als „Datenhaltung/Model“ ebenfalls richtig, AuftragService als Controller falsch. b) Anfrage Browser → Controller 1 P, Controller → Model inkl. DB-Zugriff und Rückgabe 1 P, Controller → View mit Daten 1 P, View → Browser 1 P. c) unterschiedliche Reichweite 1 P, Zuordnung am Beispiel 2 P.
Aufgabe WZ-03.3 · 18 Punkte

a) 3-Schichten-Architektur von MonteurPlus und Zusammenwirken (6 P)

Ablauf „Auftrag mit Arbeitsbericht abschließen“: Der Monteur erfasst in der App Material, Fotos und die Unterschrift des Kunden; die App speichert alles zunächst lokal in SQLite – auch im Keller ohne Netz. Sobald eine Verbindung besteht, sendet die App die Daten per HTTPS als JSON an die REST-API. Der Synchronisationsdienst prüft Berechtigung und Vollständigkeit (und ggf. Konflikte), setzt den Auftrag auf „abgeschlossen“, der Berichtsdienst erzeugt den PDF-Arbeitsbericht. Über die Repositories werden Auftrag und Bericht per SQL in PostgreSQL gespeichert. Der Server bestätigt den Empfang (z. B. HTTP 200/201), die App markiert die Daten lokal als übertragen. Ruft eine Disponentin die Auftragsübersicht auf, liest der Server den neuen Status aus der Datenbank und liefert die Seite an den Browser. Nachts exportiert der Server die abgeschlossenen Aufträge als XML per SFTP an das ERP-System.

b) Architekturskizze (5 P)

Präsentation Darstellung, Eingabe Logik Geschäftsregeln Datenhaltung Speicherung Browser (Disponenten) Web-Disposition: HTML-Seiten Plantafel (TypeScript) Monteur-App (Android) Kotlin, Offline-Logik lokale Datenbank SQLite Anwendungsserver Web-Controller + Templates REST-API Services: Auftragsverwaltung, Einsatzplanung, Synchronisation, Berichtserstellung (PDF) Repositories (Datenzugriff) Spring Boot · Java 21 · Container (Linux) PostgreSQL 16 Kunden, Aufträge, Berichte … Externe Systeme Kartendienst Geokodierung, Fahrzeiten HTTPS-API, JSON ERP-System Albers abgeschl. Aufträge XML-Datei per SFTP nachts HTTPS HTML Plantafel: REST/JSON HTTPS, REST/JSON SQL (JDBC)
Abb. L-4: Architektur von MonteurPlus (Lösungsvorschlag)

Web-Controller und Templates werden auf dem Server ausgeführt, gehören fachlich aber zur Präsentation (serverseitiges Rendering). Beide Zuordnungen sind richtig, wenn sie begründet bzw. eindeutig dargestellt sind. Die lokale SQLite-Datenbank der App kann auch in der Datenhaltungsschicht gezeichnet werden, sofern erkennbar ist, dass sie auf dem Gerät liegt.

c) Microservices oder Monolith (5 P)

Vorteile von MicroservicesNachteile von Microservices
  • Dienste unabhängig deploybar: z. B. die Einsatzplanung ändern, ohne Synchronisation und Berichte neu auszuliefern.
  • Dienste einzeln skalierbar: z. B. mehr Instanzen der Synchronisation morgens, wenn alle Monteure gleichzeitig abgleichen, oder bei vielen SaaS-Kunden.
  • Fehlerisolation: Hängt die PDF-Erzeugung, funktioniert die Synchronisation weiter.
  • Technologie je Dienst frei wählbar; kleinere, überschaubare Codebasen.
  • Verteiltes System: Kommunikation über das Netz zwischen den Diensten, Latenz, Fehlerbehandlung bei Ausfällen einzelner Dienste.
  • Datenkonsistenz: Auftrag und Bericht liegen in getrennten Datenbanken, eine gemeinsame Transaktion ist nicht mehr einfach möglich.
  • Hoher Betriebsaufwand: viele Container, Orchestrierung, Monitoring, verteiltes Logging, je Dienst eine Pipeline.
  • Integrationstests und Fehlersuche über Dienstgrenzen sind aufwendiger; Schnittstellen müssen versioniert werden.

Empfehlung: Für ein Team von acht Entwicklerinnen und Entwicklern, ein Produkt im Aufbau und einen einzigen Administrator empfiehlt sich zunächst ein modularer Monolith: ein Deployment, intern aber nach Fachbereichen (Aufträge, Einsatzplanung, Synchronisation, Berichte) mit klaren Schnittstellen getrennt. Die bestehende Pipeline kann weiterverwendet werden, Komplexität und Betriebsaufwand bleiben beherrschbar. Wächst die Last durch viele SaaS-Kunden, lassen sich einzelne Module (z. B. Synchronisation) später gezielt als Microservice herauslösen.

d) Kein direkter Datenbankzugriff der App (2 P)

Zwei davon: Sicherheit – der Datenbankserver bleibt aus dem Internet unerreichbar, und es stehen keine Datenbank-Zugangsdaten in der App, die sich aus der APK auslesen ließen. · Geschäftsregeln und Berechtigungen werden zentral auf dem Server geprüft und können nicht von einer manipulierten App umgangen werden. · Entkopplung: Das Datenbankschema kann sich ändern, ohne dass alle App-Versionen auf 140 Geräten angepasst werden müssen; die REST-API bleibt stabil. · Weniger offene Datenbankverbindungen, Schichtenprinzip wird eingehalten.

Bewertung: a) drei Schichten mit den Komponenten aus Anlage 7 je 1 P, schlüssiger Ablauf durch die Schichten (lokal speichern, Übertragung REST/JSON, Verarbeitung, Speicherung, Rückmeldung) 3 P. b) alle Komponenten einer Schicht zugeordnet 2 P, externe Systeme 1 P, Kommunikationswege mit Protokoll/Format beschriftet 2 P. c) je Vor-/Nachteil 1 P (max. 4), Empfehlung mit Bezug auf Team/Situation 1 P – eine begründete Empfehlung für Microservices ist ebenfalls möglich. d) je Argument 1 P.

Erklärung: Teilaufgabe a) entspricht W22 T1 A2a – dort gab es 6 P für Schichten und Zusammenarbeit. Wer nur die drei Schichten aufzählt, erhält etwa die Hälfte; erwartet wird der Weg einer Anfrage durch die Schichten und zurück.

WZ-04 · Compiler vs. Interpreter

Aufgabe WZ-04.1 · 7 Punkte

a) Unterschied (2 P)

Ein Compiler übersetzt den gesamten Quellcode vor der Ausführung in Maschinencode und erzeugt eine ausführbare Datei, die anschließend ohne Compiler ausgeführt wird. Ein Interpreter liest den Quellcode zur Laufzeit Anweisung für Anweisung, übersetzt sie und führt sie sofort aus; es entsteht keine ausführbare Datei, und der Interpreter wird bei jeder Ausführung benötigt.

b) Zuordnung (3 P)

SpracheCompiler → MaschinencodeInterpreterCompiler → Bytecode → VM
C++X
PythonX(auch akzeptiert)
JavaX
GoX
PHPX
C#X (IL, CLR)

c) Vor- und Nachteil des Interpreters (2 P)

Vorteil (einer): plattformunabhängiger Quellcode – läuft überall, wo der Interpreter installiert ist · schneller Entwicklungs- und Testzyklus ohne Übersetzungsschritt, interaktives Ausprobieren.
Nachteil (einer): langsamere Ausführung, da zur Laufzeit übersetzt wird · Fehler (auch Syntax- und Typfehler) zeigen sich erst bei der Ausführung der betreffenden Zeile · Interpreter muss auf dem Zielsystem installiert sein · Quellcode wird mit ausgeliefert.

Bewertung: a) je Prinzip 1 P (Zeitpunkt der Übersetzung und ausführbare Datei ja/nein müssen erkennbar sein). b) je Sprache 0,5 P; für Python ist auch „Bytecode + VM“ richtig (CPython erzeugt intern Bytecode), Java/C# als „Compiler → Maschinencode“ ist falsch. c) je 1 P.
Aufgabe WZ-04.2 · 10 Punkte

a) Fehlerarten (4 P)

Nr.FehlerartWann/wodurch bemerkt?
(1)Typfehler (semantischer Fehler)Beim Übersetzen durch den Compiler (statische Typprüfung), die IDE markiert ihn schon beim Tippen: Fehler: Inkompatible Typen: int kann nicht in String konvertiert werden. Es entsteht kein Programm.
(2)Syntaxfehler (schließende Klammer fehlt)Beim Übersetzen durch den Compiler bzw. sofort in der IDE: Fehler: ')' erwartet.
(3)LaufzeitfehlerKompiliert fehlerfrei; erst bei der Ausführung dieser Zeile wird eine IndexOutOfBoundsException geworfen (Index 3 out of bounds for length 3), da gültige Indizes von 0 bis size() - 1 reichen. Korrektur: auftraege.get(auftraege.size() - 1).
(4)Logischer FehlerKeine Fehlermeldung: 250 / 4 ist eine Ganzzahldivision (= 62), erst danach wird in double umgewandelt → 62,0 statt 62,5. Bemerkt nur durch Tests mit erwarteten Ergebnissen, Code-Review, Debugging oder aufmerksame Nutzer. Korrektur: (double) summeMinuten / anzahl.

b) Python (2 P)

Python ist dynamisch typisiert und wird interpretiert. Zeile 12 ist gültig – plz verweist einfach auf eine Ganzzahl. Der Fehler wird erst zur Laufzeit bemerkt, wenn Zeile 87 tatsächlich ausgeführt wird: AttributeError: 'int' object has no attribute 'zfill' – möglicherweise erst nach langer Laufzeit des Imports oder nur bei bestimmten Datensätzen. In Java (Ausschnitt 1) prüft der Compiler die Typen vor der Ausführung, der Fehler fällt also schon beim Übersetzen auf. (Zusatz: Eine Postleitzahl gehört ohnehin als Text gespeichert, sonst geht die führende 0, z. B. bei 01067, verloren.)

c) Fehlersuche mit dem Debugger (4 P)

  1. Fehler reproduzierbar machen: Testfall mit bekannten Werten (250 Minuten, 4 Einsätze → erwartet 62,5).
  2. Haltepunkt in der Methode setzen, die den Durchschnitt berechnet (bei unbekannter Stelle zunächst am Anfang der Berechnung), und das Programm im Debug-Modus starten.
  3. Beim Anhalten die Variablen beobachten (Variablenansicht/Watch): summeMinuten = 250, anzahl = 4 – die Eingangswerte stimmen.
  4. Mit Step Over die Zeile ausführen: schnitt = 62.0 → hier entsteht der Fehler. Mit „Ausdruck auswerten“ zeigt summeMinuten / anzahl den Wert 62 (int) → Ursache Ganzzahldivision. Liegt die Berechnung in einer aufgerufenen Methode, mit Step Into hineinspringen; über den Aufrufstapel sieht man, von wo sie aufgerufen wurde.
  5. Code korrigieren, Unit-Test ergänzen und erneut ausführen.

Zum Ausprobieren: java\11_Werkzeuge\Aufgabe_WZ_04_2.java enthält die Ausschnitte (3) und (4) mit Korrektur; Ausgabe des Programms:

(3) Laufzeitfehler:
    IndexOutOfBoundsException: Index 3 out of bounds for length 3
    korrigiert: A-1003
(4) Logischer Fehler (keine Fehlermeldung!):
    fehlerhaft:  Durchschnitt = 62.0 min
    korrigiert:  Durchschnitt = 62.5 min
OK     Korrektur (4): erwartet 62.5, erhalten 62.5
OK     Fehler (4) reproduziert: erwartet 62.0, erhalten 62.0
OK     Korrektur (3): erwartet A-1003, erhalten A-1003
Bewertung: a) je Ausschnitt Fehlerart 0,5 P und Zeitpunkt/Erkennung 0,5 P. b) Zeitpunkt (Laufzeit, erst in Zeile 87) 1 P, Begründung (dynamische Typisierung/Interpreter) mit Vergleich zu Java 1 P. c) je sinnvoll eingesetzter Debugger-Funktion 1 P (max. 3), nachvollziehbares Vorgehen bis zur Ursache 1 P.
Aufgabe WZ-04.3 · 16 Punkte

a) Java vom Entwicklerrechner bis zum Linux-Server (4 P)

  1. Auf dem Windows-Rechner bzw. in der Pipeline übersetzt der Compiler javac (über Maven) die .java-Dateien in Bytecode (.class-Dateien) – plattformunabhängigen Zwischencode für eine gedachte Maschine, nicht für einen konkreten Prozessor. Die Klassen werden zu einer JAR-Datei bzw. einem Container-Image gepackt.
  2. Dieselbe JAR-Datei wird ohne erneute Übersetzung auf den Linux-Server gebracht.
  3. Dort lädt die Java Virtual Machine (Eclipse Temurin 21 für Linux) den Bytecode, prüft ihn und führt ihn zunächst interpretierend aus.
  4. Der JIT-Compiler erkennt häufig ausgeführte Methoden („Hotspots“) und übersetzt sie zur Laufzeit in optimierten Maschinencode für den Prozessor des Servers – dadurch läuft der Server fast so schnell wie ein direkt kompiliertes Programm.

Die Plattformunabhängigkeit („Write once, run anywhere“) entsteht, weil es für jedes Betriebssystem eine eigene JVM gibt, die denselben Bytecode ausführt.

b) Python oder C++ für die Datenübernahme (4 P)

Python (interpretiert): sehr kurzer, gut lesbarer Code; CSV-Verarbeitung mit der Standardbibliothek; schneller Test-Zyklus ohne Übersetzen – Formatprobleme in den Altdaten lassen sich schnell anpassen und der Import erneut starten. Nachteil: langsamere Ausführung, Typfehler erst zur Laufzeit.
C++ (kompiliert): deutlich schnellere Ausführung, aber höherer Entwicklungsaufwand (Speicherverwaltung, CSV-Parsing, Datenbankanbindung), längerer Entwicklungszyklus, im Team (Java/Kotlin/TypeScript) kaum Erfahrung.
Einsatzzweck: Der Import läuft einmal, mit nur ca. 60 000 Datensätzen (bei Python im Bereich von Sekunden bis Minuten) und unkritischer Laufzeit über Nacht. Der Geschwindigkeitsvorteil von C++ bringt hier nichts, die Entwicklungszeit zählt.
Empfehlung: Python (alternativ Java als Teamsprache) – geringer Aufwand, schnelle Anpassung an fehlerhafte Altdaten.

c) TypeScript und tsc (3 P)

tsc ist ein Transpiler (Source-to-Source-Compiler): Er übersetzt den TypeScript-Code vor der Auslieferung in JavaScript, denn Browser können nur JavaScript ausführen. Dabei prüft er die statischen Typangaben (z. B. auftragNr: number, Struktur der Daten aus der REST-API) und meldet Typfehler, Tippfehler in Eigenschaftsnamen oder fehlende Parameter bereits beim Übersetzen; im erzeugten JavaScript sind die Typen entfernt. Ausgeführt wird das JavaScript dann im Browser (Interpreter + JIT der JavaScript-Engine).
Vorteil: Viele Fehler fallen vor der Ausführung auf statt erst bei den Disponenten; zudem bessere IDE-Unterstützung (Autovervollständigung, sicheres Umbenennen) und eine selbstdokumentierende Schnittstelle zur REST-API.

d) Go-Programm mp-export (5 P)

da) (3 P) Der Go-Compiler (go build) prüft Syntax und Typen und übersetzt die Quelldateien des Programms und der verwendeten Pakete in Maschinencode (Objektcode) für die Zielplattform (hier Windows, x86-64). Der Linker fügt diesen Objektcode mit dem Code der benötigten Bibliotheken (Go-Standardbibliothek, Fremdpakete) und der Go-Laufzeitumgebung zusammen, löst die Verweise auf Funktionen in anderen Paketen auf und erzeugt die ausführbare Datei mp-export.exe. Go bindet die Bibliotheken in der Regel statisch ein – deshalb ist das Ergebnis eine einzelne Datei, die ohne weitere Installation läuft (Anforderung aus Anlage 8).

db) (2 P) Die ausführbare Datei enthält Maschinencode und ein Dateiformat, die an Betriebssystem und Prozessor gebunden sind: Windows nutzt das PE-Format (.exe) und Windows-Systemaufrufe, Linux das ELF-Format und Linux-Systemaufrufe (ggf. auch eine andere Prozessorarchitektur). Deshalb muss für jede Zielplattform eigens übersetzt und gelinkt werden – bei Go per Cross-Compiling, z. B. GOOS=linux GOARCH=amd64 go build. Anders als bei Java gibt es keine virtuelle Maschine, die plattformneutralen Code ausführt.

Bewertung: a) Bytecode 1 P, JVM/Plattformunabhängigkeit 1 P, Interpretation und JIT 1 P, Gesamtablauf Windows → Linux 1 P. b) Bewertung Python 1 P, Bewertung C++ 1 P, Bezug zum Einsatzzweck (einmalig, Datenmenge, Laufzeit unkritisch) 1 P, begründete Empfehlung 1 P (C++ nur mit überzeugender Begründung). c) Übersetzung TS → JS und Ausführung im Browser 1 P, Typprüfung beim Übersetzen 1 P, Vorteil 1 P. da) Kompilieren in Maschinencode 1 P, Aufgabe des Linkers 1 P, eigenständige Datei (statisches Linken) 1 P. db) Plattformabhängigkeit des Maschinencodes/Formats 1 P, Folge (je Plattform eigener Build) 1 P.

WZ-05 · Klassenbibliotheken, Frameworks & Dokumentation

Aufgabe WZ-05.1 · 6 Punkte

a) Bibliothek vs. Framework (2 P)

Eine Klassenbibliothek ist eine Sammlung wiederverwendbarer Klassen und Methoden, die der eigene Code bei Bedarf aufruft; die Ablaufsteuerung bleibt beim eigenen Programm (z. B. TerminKern: MonteurPlus ruft istFeiertag() auf). Ein Framework gibt Struktur und Ablauf der Anwendung vor; der eigene Code wird an vorgesehenen Stellen eingefügt und vom Framework aufgerufen – Inversion of Control (z. B. Spring Boot nimmt HTTP-Anfragen an und ruft die passende Controller-Methode auf).

b) Vor- und Nachteil einer umfangreichen PDF-Bibliothek (4 P)

Vorteil (einer, beschrieben): PDF-Erzeugung ist komplex (Schriften, Seitenumbrüche, Tabellen, Fotos, Unterschrift, ggf. PDF/A für die Archivierung). Eine erprobte Bibliothek spart Entwicklungszeit und Kosten, ist von vielen Nutzern getestet und enthält dadurch weniger Fehler als eine Eigenentwicklung; das Team kann sich auf die Fachlogik der Arbeitsberichte konzentrieren. Fehlerbehebungen und Sicherheitsupdates kommen vom Hersteller.

Nachteil (einer, beschrieben): Abhängigkeit vom Hersteller bzw. Projekt – wird die Bibliothek nicht mehr gepflegt oder ändert sich die Lizenz, muss man sie mit großem Aufwand ersetzen. Weitere: Lizenzbedingungen und -kosten (PdfMaker Core: AGPL oder 2 400 € pro Jahr, Anlage 11), Einarbeitungsaufwand in eine umfangreiche API, größere Anwendung, obwohl nur ein Bruchteil genutzt wird, Sicherheitslücken im fremden Code.

Bewertung: a) Bibliothek 1 P, Framework mit Steuerungsumkehr 1 P. b) Vorteil 2 P, Nachteil 2 P (jeweils 1 P für das Stichwort, 1 P für die Beschreibung mit Begründung bzw. Bezug zur Situation).
Aufgabe WZ-05.2 · 10 Punkte

a) Aufgaben von Maven bei Abhängigkeiten (3 P)

In der pom.xml werden nur die direkten Abhängigkeiten mit ihren Koordinaten (groupId, artifactId, version) deklariert. Maven lädt die passenden JAR-Dateien aus einem zentralen Repository (Maven Central bzw. Firmen-Repository) in den lokalen Zwischenspeicher und bindet sie beim Kompilieren, Testen und Packen ein. Dabei löst Maven die transitiven Abhängigkeiten automatisch auf: TerminKern benötigt seinerseits feiertage-de und json-mini; beide stehen nicht in der pom.xml, werden aber trotzdem geladen (im Abhängigkeitsbaum eingerückt unter TerminKern). Außerdem verwaltet Maven Versionen (Spring Boot gibt die Versionen für spring-boot-starter-web und junit-jupiter vor, daher fehlt dort die Versionsangabe), löst Versionskonflikte auf und trennt Gültigkeitsbereiche: junit-jupiter hat den Scope test und gelangt nicht in das ausgelieferte Programm.

b) Release Notes und SemVer (4 P)

VersionAussage / InhaltUpdate ohne Codeänderung?
2.4.2PATCH: nur abwärtskompatible Fehlerbehebungen – Berechnung des Ostermontags korrigiert, json-mini wegen einer Denial-of-Service-Lücke auf 0.9.3 aktualisiert.Ja.
2.5.0MINOR: neue, abwärtskompatible Funktion istBrueckentag(); feiertage(int) wird als veraltet (deprecated) markiert und im nächsten Major-Release entfernt.Ja; der Compiler warnt aber an den 14 Stellen, die feiertage(int) nutzen.
3.0.0MAJOR: inkompatible Änderungen – Paket umbenannt, feiertage(int) entfernt, Java 21 als Mindestversion (beim Server bereits erfüllt).Nein: alle Imports und die 14 Aufrufe müssen angepasst und gründlich getestet werden.

Empfehlung: kurzfristig auf 2.4.2 aktualisieren – die Sicherheitslücke wird geschlossen, das Risiko ist minimal. Ebenfalls gut vertretbar: 2.5.0 (abwärtskompatibel, enthält als spätere Version in der Regel auch die Korrekturen aus 2.4.2; die Deprecation-Warnungen helfen, die 14 Stellen schon auf feiertage(Year, Bundesland) umzustellen). Den Umstieg auf 3.0.0 als eigenes Ticket mit Tests planen.

c) Risiko json-mini und Maßnahmen (3 P)

Risiko: json-mini 0.9.2 ist eine transitive Abhängigkeit, die in der pom.xml gar nicht auftaucht, und enthält eine bekannte Schwachstelle: Tief verschachtelte JSON-Eingaben können eine Endlosschleife auslösen. Verarbeitet der Server über TerminKern solche Daten, kann ein Angreifer (oder eine fehlerhafte Eingabe) den Server blockieren – MonteurPlus wäre für Disponenten und Monteure nicht verfügbar (Schutzziel Verfügbarkeit). Zudem signalisiert die Version 0.x eine noch instabile Bibliothek.

Maßnahmen (zwei): automatischer Schwachstellen-Scan aller (auch transitiven) Abhängigkeiten in der Pipeline, z. B. OWASP Dependency-Check, GitLab Dependency Scanning, Dependabot/Renovate, mit Abbruch bei kritischen Lücken · SBOM erstellen und laufend mit Schwachstellendatenbanken abgleichen · Sicherheitshinweise und Release Notes der Bibliotheken verfolgen, regelmäßige Update-Termine · betroffene transitive Version gezielt anheben (Maven dependencyManagement), bis die direkte Abhängigkeit aktualisiert ist · vor dem Einsatz neuer Bibliotheken Pflegezustand und Abhängigkeiten prüfen, Anzahl der Abhängigkeiten gering halten.

Bewertung: a) Laden aus zentralem Repository 1 P, transitive Abhängigkeiten am Beispiel 1 P, Versionen/Scope 1 P. b) je Version Aussage und Update-Fähigkeit 1 P, Empfehlung mit Begründung 1 P (2.4.2 oder 2.5.0). c) Risiko 1 P, je Maßnahme 1 P.

Erklärung: Entscheidend für den englischen Text sind die Signalwörter: Fixed und Security (Patch), New und Deprecated (Minor), BREAKING (Major). Genau das bildet SemVer in der Versionsnummer ab.

Aufgabe WZ-05.3 · 16 Punkte

a) Drei Aspekte der Dokumentation (6 P)

b) Javadoc-Kommentar (5 P)

/**
 * Sucht den frühesten freien Einsatztermin eines Monteurs ab einem Starttag.
 *
 * <p>Geprüft werden höchstens 30 aufeinanderfolgende Tage, beginnend mit
 * {@code ab}. Für normale Aufträge werden nur Arbeitstage laut
 * Arbeitszeitmodell berücksichtigt, die im Bundesland des Kalenders keine
 * Feiertage sind. Bei Notdienst-Aufträgen ({@code notdienst = true}) wird jeder
 * Tag geprüft, also auch Wochenenden und Feiertage. Innerhalb eines Tages
 * liefert der Einsatzplan des Monteurs den frühesten freien Zeitraum der
 * benötigten Dauer.</p>
 *
 * @param m         Monteur, für den ein Termin gesucht wird; nicht {@code null}
 * @param ab        erster Tag der Suche (wird mitgeprüft); nicht {@code null}
 * @param dauer     benötigte Einsatzdauer; muss positiv sein (größer als 0)
 * @param notdienst {@code true}, wenn auch Wochenenden, arbeitsfreie Tage und
 *                  Feiertage berücksichtigt werden sollen (Notdienst-Auftrag)
 * @return Beginn (Datum und Uhrzeit) des frühesten freien Termins oder ein leeres
 *         {@link Optional}, wenn innerhalb von 30 Tagen kein passender Termin frei ist
 * @throws IllegalArgumentException wenn {@code dauer} 0 Minuten lang oder negativ ist
 * @throws NullPointerException     wenn {@code m}, {@code ab} oder {@code dauer}
 *                                  {@code null} ist
 * @since 1.0
 * @see Kalender#istFeiertag(LocalDate)
 */
public Optional<LocalDateTime> naechsterFreierTermin(
        Monteur m, LocalDate ab, Duration dauer, boolean notdienst) { … }

Geprüft: Die vollständige Klasse mit diesem Kommentar steht in java\11_Werkzeuge\Aufgabe_WZ_05_3.java; sie kompiliert und erzeugt mit javadoc -Xdoclint:all für EinsatzKalender keine Warnungen. Programmausgabe des Beispiels (Fr 02.10.2026 belegt, 03.10. Feiertag und Samstag):

Normaler Auftrag ab Fr 02.10.2026: Optional[2026-10-05T07:30]
Notdienst ab Fr 02.10.2026:        Optional[2026-10-03T07:30]
Ist 03.10.2026 Feiertag? true
Dauer 0 -> IllegalArgumentException: dauer muss positiv sein: PT0S

c) Unterklasse statt Änderung der Bibliothek (3 P)

Drei Argumente: Updates bleiben möglich – Änderungen im Quellcode der Bibliothek gingen beim nächsten Update von TerminKern verloren bzw. müssten bei jedem Update (auch bei Sicherheitsupdates wie 2.4.2) erneut eingepflegt werden; man bliebe auf einer alten Version „hängen“. · Trennung von allgemeiner und fachlicher Logik – TerminKern ist eine allgemeine Kalenderbibliothek und kennt keine Monteure, Einsatzpläne oder Arbeitszeitmodelle; diese MonteurPlus-spezifische Logik gehört in eigenen Code. · Vorgesehener Erweiterungsweg – Vererbung nutzt die öffentliche API (istFeiertag) ohne Eingriff in fremden Code (Open-Closed-Prinzip); die Erweiterung lässt sich eigenständig versionieren, testen und von anderen Teams einbinden. · Lizenz/Verantwortung – geänderter Bibliothekscode wäre ein eigener „Fork“, für den man selbst verantwortlich ist (Apache 2.0 verlangt z. B., Änderungen zu kennzeichnen).

d) Weitere Bestandteile (2 P)

Zwei davon: Einstieg/Installationsanleitung (Maven-Koordinaten, Voraussetzungen wie TerminKern-Version und Java 21) · Codebeispiele bzw. Tutorial für typische Anwendungsfälle · Changelog/Versionshinweise · Migrationshinweise bei inkompatiblen Änderungen · Überblick über Aufbau und Klassen (Architektur) · bekannte Einschränkungen · Lizenzhinweise · Ansprechpartner/Wartung.

Bewertung: a) je Aspekt 2 P (1 P Aspekt benannt, 1 P konkret mit Bezug auf Anlage 10 beschrieben). b) Beschreibung inkl. Verhalten bei Notdienst und 30-Tage-Grenze 1 P, alle vier @param 2 P, @return inkl. leerem Optional 1 P, @throws 1 P (@since/@see optional). c) je Argument 1 P. d) je Bestandteil 1 P.

Erklärung: Die Originalaufgabe W21 T1 A1bb fragte allgemein nach drei Aspekten (6 P). Wer konkret auf den Code eingeht (Parameter, Rückgabe, Ausnahmen, Kompatibilität zur Basisbibliothek), sammelt die Punkte sicherer als mit allgemeinen Floskeln wie „verständlich schreiben“.

WZ-06 · Open Source & Lizenzen

Aufgabe WZ-06.1 · 6 Punkte

a) Open Source (3 P)

Open-Source-Software ist Software, deren Quellcode öffentlich zugänglich ist und deren Lizenz jedem erlaubt, die Software für beliebige Zwecke (auch kommerziell) zu nutzen, zu untersuchen, zu verändern und – verändert oder unverändert – weiterzugeben. Welche Bedingungen dabei gelten (z. B. Lizenzhinweise beilegen, Änderungen offenlegen), legt die jeweilige Lizenz fest; anerkannte Open-Source-Lizenzen erfüllen die Open Source Definition der OSI (z. B. MIT, Apache 2.0, GPL). Das Urheberrecht bleibt beim Autor; meist ist die Nutzung kostenlos.

b) Einsatz ohne Einschränkung? (2 P)

Nein. Open Source bedeutet nicht „rechtefrei“: Man darf eine Bibliothek nur unter den Bedingungen ihrer Lizenz einsetzen. Copyleft-Lizenzen wie die GPL verlangen z. B., dass ein Programm, das die Bibliothek enthält, bei Weitergabe ebenfalls unter der GPL mit vollständigem Quellcode weitergegeben wird – das widerspricht dem proprietären Modell von MonteurPlus. Auch permissive Lizenzen verlangen zumindest Lizenz- und Copyright-Hinweise.

c) Beispiele (1 P)

Permissiv: MIT, BSD, Apache 2.0. Copyleft: GPL, AGPL, LGPL (schwach), MPL 2.0 (schwach), EPL 2.0 (schwach).

Bewertung: a) offener Quellcode 1 P, Nutzungs-/Änderungs-/Weitergaberechte 1 P, Bedingungen durch die Lizenz 1 P. b) „Nein“ mit Verweis auf Lizenzbedingungen 1 P, Beispiel/Begründung (z. B. Copyleft) 1 P. c) je Beispiel 0,5 P.
Aufgabe WZ-06.2 · 10 Punkte

a) Software-Arten (4 P)

Software-ArtQuellcode verfügbarVerändern erlaubtWeitergabe erlaubtkostenlos nutzbar
Open Sourcejajaja (unter Lizenzbedingungen)ja (in der Regel)
Freewareneinneinmeist ja / eingeschränktja (oft nur privat → eingeschränkt)
Sharewareneinneinja/eingeschränkt (Testversion)eingeschränkt (Testzeitraum/Funktionsumfang)
Proprietäre Softwareneinneinneinnein

b) Bibliotheken Nr. 1, 3 und 4 (6 P)

Nr.Einsatz zulässig?Begründung und Pflichten
1 ChartLite (MIT)jaPermissive Lizenz. Die JavaScript-Datei wird an die Browser ausgeliefert, also weitergegeben; dafür verlangt MIT nur, den Copyright- und Lizenzhinweis in allen Kopien beizubehalten (z. B. Kommentarkopf der Datei, Seite „Lizenzen/Third-Party-Notices“). Der eigene Code von MonteurPlus darf proprietär bleiben.
3 GeoKit (LGPL-3.0)ja, mit AuflagenSchwaches Copyleft: Die proprietäre App darf GeoKit nutzen, solange die Bibliothek unverändert und als eigenständige, austauschbare Komponente eingebunden ist. Pflichten bei Verteilung der App: Hinweis auf GeoKit und den LGPL-Lizenztext (samt GPL-Text) mitliefern, den Quellcode von GeoKit bzw. ein Angebot dafür bereitstellen, Änderungen an GeoKit selbst unter LGPL offenlegen und den Austausch der Bibliothek durch eine andere Version nicht verhindern. Hinweis: Bei Android-Apps ist die Austauschbarkeit technisch anspruchsvoll – vor der Veröffentlichung im Play Store rechtlich prüfen lassen.
4 SignPad (GPL-3.0)neinStarkes Copyleft: Die Monteur-App wird an Albers und künftig über den Play Store weitergegeben. Mit SignPad entsteht ein abgeleitetes Werk, das als Ganzes unter der GPL-3.0 lizenziert und mit vollständigem Quellcode weitergegeben werden müsste. Das widerspricht dem Ziel, Quellcode und Rechte bei Lindner Digital zu behalten. Alternative: Bibliothek mit permissiver Lizenz, kommerzielle Lizenz beim Autor anfragen oder das Unterschriftenfeld selbst entwickeln.
Bewertung: a) je vollständig richtiger Zeile 1 P (bei Freeware/Shareware sind „ja“ und „eingeschränkt“ in den Spalten Weitergabe/kostenlos gleichwertig). b) je Bibliothek Entscheidung 1 P, Begründung mit den konkreten Pflichten 1 P.
Aufgabe WZ-06.3 · 18 Punkte

a) Bibliotheken Nr. 5 bis 8 (8 P)

Nr.Einsatz?Begründung / Maßnahme
5 PdfMaker Core (AGPL-3.0 oder kommerziell)unter AGPL: nein · mit kommerzieller Lizenz: ja, mit AuflagenDer Server wird als SaaS über das Netz für Kunden betrieben. Die AGPL verlangt, dass Nutzern eines Netzdienstes, der auf der AGPL-Software aufbaut, der vollständige Quellcode angeboten wird – hier also der Quellcode des MonteurPlus-Servers. Das ist mit dem proprietären Modell unvereinbar. Maßnahme: kommerzielle Lizenz (2 400 € pro Jahr, Dual Licensing) erwerben oder eine Alternative mit permissiver Lizenz wählen.
6 RouteOpt SDK (proprietär)ja, mit AuflagenNutzung nur mit gültigem Lizenzvertrag; Kosten von 3 € je Monteur und Monat einplanen (bei Albers 140 × 3 € = 420 € pro Monat, mit jedem SaaS-Kunden mehr). Laut Vertrag ist nur die Nutzung „für eigene interne Zwecke“ erlaubt – der Betrieb für Albers und weitere Kunden ist davon voraussichtlich nicht gedeckt. Maßnahme: mit dem Hersteller eine SaaS-/Mandantenlizenz vereinbaren, sonst droht eine Vertragsverletzung.
7 csv-quick (keine Lizenz)neinOhne Lizenz liegen alle Rechte beim Urheber; Kopieren, Nutzen und Ändern ist nicht erlaubt – auch nicht für einen einmaligen internen Import. Zudem ist die Qualität unklar (Version 0.3, Privatperson). Maßnahme: Autor um eine Lizenz bitten oder eine Alternative verwenden (z. B. CSV-Funktionen der Standardbibliothek bzw. eine Bibliothek unter Apache-/MIT-Lizenz).
8 DbMigrate (GPL-2.0)jaDbMigrate läuft nur intern als Werkzeug in der eigenen Pipeline; es wird weder in MonteurPlus eingebaut noch weitergegeben. Die Copyleft-Pflichten der GPL greifen erst bei Weitergabe; interne Nutzung ist uneingeschränkt erlaubt, der Code von MonteurPlus wird nicht berührt. Auflage: neu prüfen, falls DbMigrate später an Kunden mitgeliefert wird (z. B. bei einer Installation im Rechenzentrum eines Kunden).

b) Vor- und Nachteile von Open-Source-Bibliotheken (4 P)

Vorteile (zwei): keine Lizenzkosten – wichtig, weil bei wachsender Kundenzahl keine Gebühren je Nutzer anfallen · Quellcode einsehbar: Qualität und Sicherheit prüfbar, Fehler selbst analysieren und notfalls beheben · große Community, weite Verbreitung, viel Wissen und schnelle Fehlerbehebung bei aktiven Projekten · keine Abhängigkeit von einem Hersteller, bei Einstellung kann das Projekt weitergeführt (geforkt) werden.

Nachteile (zwei): Lizenzpflichten müssen geprüft und eingehalten werden; Copyleft (Nr. 4, 5) kann das Geschäftsmodell gefährden → Aufwand für Lizenz-Compliance · keine Gewährleistung und kein garantierter Support (Haftungsausschluss) – gegenüber Albers haftet Lindner Digital trotzdem selbst · Fortbestand unsicher (Projekt wird eingestellt oder Lizenz geändert) · Sicherheitslücken sind öffentlich sichtbar, Updates muss man selbst verfolgen (vgl. json-mini).

Fazit für die Geschäftsführung: Open Source ja, aber mit festem Prüfprozess (Lizenz, Pflegezustand, Sicherheit) vor jedem Einsatz.

c) GPL-Code in eine MIT-Bibliothek kopieren (3 P)

Nicht zulässig. Der kopierte SignPad-Code bleibt urheberrechtlich geschützt und steht unter der GPL-3.0. Wird er in lindner-utils übernommen, entsteht ein abgeleitetes Werk, das bei der Veröffentlichung insgesamt unter der GPL-3.0 stehen muss. Eine Veröffentlichung unter MIT würde die GPL verletzen, weil MIT u. a. erlaubt, den Code in proprietäre Software einzubauen – GPL-Code lässt sich nicht in eine permissive Lizenz „umlizenzieren“ (umgekehrt wäre MIT-Code in einem GPL-Projekt zulässig). Außerdem würde lindner-utils selbst copyleft-pflichtig und wäre in MonteurPlus nicht mehr einsetzbar. Lösung: die Funktionen ohne Kopie selbst neu entwickeln, eine Bibliothek mit permissiver Lizenz nutzen oder den Rechteinhaber von SignPad um eine Lizenz unter MIT bitten (nur er kann umlizenzieren).

d) SBOM (3 P)

Eine Software Bill of Materials ist eine maschinenlesbare, vollständige „Stückliste“ aller Komponenten eines Softwareprodukts – einschließlich der transitiven Abhängigkeiten – mit Name, Version, Herkunft, Lizenz und Prüfsumme (Formate SPDX oder CycloneDX). Sie wird in der Pipeline automatisch für jede Version erzeugt (z. B. per Maven-Plugin).

Nutzen am Beispiel: FeiertageDE und json-mini stehen nicht in der pom.xml, sondern kommen über TerminKern ins Produkt. Die SBOM führt sie trotzdem auf. Als die Denial-of-Service-Lücke in json-mini 0.9.2 bekannt wurde, hätte ein Abgleich der SBOM mit Schwachstellendatenbanken sofort gezeigt, dass Server-Version 1.3.0 betroffen ist (Schwachstellenmanagement). Außerdem lassen sich ihre Lizenzen (BSD-3-Clause, MIT) für Lizenzprüfung und Lizenzhinweise gegenüber den SaaS-Kunden erfassen. Der EU Cyber Resilience Act verlangt von Herstellern künftig eine SBOM.

Bewertung: a) je Bibliothek Entscheidung 1 P und Begründung/Maßnahme 1 P (Nr. 5: „nein“ und „ja mit kommerzieller Lizenz“ gleichwertig, wenn die AGPL-Problematik im SaaS-Betrieb erkannt wird; Nr. 8: „nein“ nur mit nachvollziehbarer Begründung, z. B. Unternehmensrichtlinie). b) je Vor-/Nachteil 1 P. c) Ergebnis 1 P, Begründung (Copyleft/Kompatibilität) 1 P, Alternative 1 P. d) Definition inkl. transitiver Abhängigkeiten 1 P, Nutzen mit Bezug auf das Beispiel 2 P.

Erklärung: Der Kern aller Lizenzfragen ist immer derselbe: Welche Lizenz, und wird die Software weitergegeben (App, Download, Browser-JavaScript) oder nur intern bzw. als Netzdienst genutzt? Bei der AGPL reicht schon der Netzdienst. In W22 genügte für „Darf jede OSS-Bibliothek eingesetzt werden?“ (2 P) die Antwort „Nein, Lizenzbedingungen beachten, z. B. GPL – Offenlegung des Quellcodes“.