AuDoscore/ScExFuSS

Automatische Bewertung von Java- und Scala-Hausaufgaben

Viele Studierende üben früh objekt-orientierte oder funktionale Programmierung durch das selbständige Implementieren von Hausaufgaben. Die immensen Teilnehmerzahlen und divergierenden Lösungsansätze erschweren es Dozierenden, die Hausaufgaben (oft Prüfungsleistungen) nach einem einheitlichen Maßstab zu bewerten.
Deshalb haben wir 2013 (damals auf Basis von Java-1.7, JUnit-4 und Scala-2.12) eine Erweiterung von JUnit entwickelt, deren Quellen wir unter https://github.com/FAU-Inf2/AuDoscore (Java) bzw. https://github.com/FAU-Inf2/ScExFuSS (Scala) veröffentlichen. Annotationen versehen Testfälle mit einer Bonus- oder Malus-Wertung. Die Ergebnisse der Testausführung werden erfasst und daraus vollautomatisch eine Gesamtpunktzahl errechnet. Die Bewertung erfolgt dabei in vier Stufen, wobei jede ggf. sofort ein ausführliches Feedback liefert.
Im Jahr 2025 haben wir AuDoscore und ScExFuSS umfassend überarbeitet, nachdem zentrale Komponenten wegen der abrupten Evolution von Java, JUnit und Scala nicht mehr durch stetige Anpassungen lauffähig waren. Seit Java-25 ist der SecurityManager als Sicherheitsinfrastruktur deaktiviert. Durch die starke Einschränkung der Java-Compiler-API wurde sie für unsere Zwecke unbrauchbar. Wegen der syntaktischen Änderungen am Quell- und Byte-Code wurde die bisherige musterbasierte Problemerkennung nicht-deterministisch. Neuere JUnit-Versionen haben grundlegend andere (zu den alten inkompatible) Erweiterungsmechanismen.
Daraus ergaben sich u.a. folgende Fragen:
- Wie sicher verhindern, dass Studierende (un)absichtlich das Bewertungssystem selbst stören (bislang durch SecurityManager)?
- Wie erkennen, wenn Studierende explizit verbotene API-Funktionen nutzen (deklarierte @Forbidden/@NotForbidden-Annotationen)?
- Wie bei der Bewertung berücksichtigen, dass Studierende aufeinander aufbauende Funktionen fehlerhaft implementieren (Folgefehler)?
- Wie AuDoscore und ScExFuSS in die neueste JUnit-Infrastruktur integrieren?
Zur Lösung in AuDoscore nutzen wir nunmehr das "Classfile-Package" aus der Java-25-API. Als Ersatz für den SecurityManager und zur Umsetzung der "@[Not]Forbidden"-Annotationen untersuchen wir damit direkt den Bytecode nach gefährlichen oder verbotenen Funktionsaufrufen. Zur Umgehung von Folgefehlern transplantieren wir damit Klassen, Methoden oder Felder aus dem Bytecode der Musterlösung in die studentische. Dabei sind viele schwierige Sonderfälle (z.B. wegen "Type Erasure", "Lambdas" u.v.m.) zu behandeln, wozu wir ggf. auch Teile des Bytecodes transferieren, die nicht unmittelbar im Code-Block der zu ersetzenden Methode stehen und übersetzen die Tests für jeden Testfall passend neu.
Zur Lösung in ScExFuSS verwenden wir aktuell die vom Compiler erzeugen TASTy-Dateien (Typed Abstract Syntax Trees) mittels des "Scala-3 Tasty-Inspectors". Als Ersatz für den SecurityManager und zur Behandlung der "@[Not]Forbidden"-Annotationen prüfen wir statisch, welche Funktionen tatsächlich verwendet werden. Die Folgefehler-Funktion auf Basis der TASTy-Dateien ist nun erstmals auch für Scala verfügbar.
Zwecks Migration zu JUnit-6 haben wir AuDoscore, ScExFuSS und alle Tests auf JUnit-Jupiter portiert. Das "Einklinken" in den gesamten Prozess der Testausführung und das Protokollieren der Bewertungsereignisse wurde dazu von Grund auf neu implementiert. Infolge dessen haben wir auch alle vorhandenen Selbsttests aktualisiert und weitere ergänzt, um sicherzustellen, dass alle Änderungen und auch alle neuen Sprachmittel von Java-25, Scala-3 und JUnit-6 korrekt behandelt werden.

Publikationen

2017