Dozentron kompiliert die Abgaben DOCH nicht sauber neu
Hier eine Kopie eins Nachrichtenverlaufs aus dem Helpdesk:
Leon Ismaiel:
Glaube ich habe ein Bug in den Tests von Abstrakter Datentyp : Matrix gefunden : [Screenshot]
Der Test schlägt nämlich nur online fehl, in IntelliJ aber nicht
Meine Antwort:
Vielen Dank, Herr Ismaiel. Da haben sie tatsächlich einen Fehler in Dozentron gefunden! Und als Belohnung erkläre ich Ihnen auch, was da schief geht. Achtung es wird technisch:
Bei der Fehlermeldung gibt es zwei interessante Dinge, die auf die Quelle des Fehlers hinweisen - die ich aber auch auf den ersten Blick übersehen habe.
Es handelt sich hier um einen Laufzeitfehler. Normalerweise erhalten Sie bei Code, in dem Methoden fehlen ja keinen
java.lang.NoSuchMethodError
beim Ausführen, sondern der Compiler weigert sich schon, den Code überhaupt zu übersetzen. So etwas kann prinzipiell schon einmal nur zu Stande kommen, wenn beim kompilieren des Codes gewisse Klassen vorhanden waren, die bei der Ausführung dann aber fehlen - zum Beispiel, wenn man vergessen hat eine Library einzubinden.Der Text der Exception ist leider von der API etwas seltsam formuliert, weist aber trotzdem auf das genauere Problem hin:
de.thm.mni.aud.OneDimDoubleMatrix.multiply(Lde/thm/mni/aud/OneDimDoubleMatrix;)Lde/thm/mni/aud/DoubleMatrix;
. Es geht um die MethodeOneDimDoubleMatrix.multiply(OneDimDoubleMatrix)
. Jetzt werden Sie (wie ich ursprünglich auch) sagen, dass die Methode ja in Ihrem Code existiert, aber das stimmt nicht genau. Sie haben eine Methode namensOneDimDoubleMatrix.multiply(DoubleMatrix)
- die gleiche Methode, die auch im Interface definiert ist. In Java werden Methoden über ihre Signatur identifiziert - das heißt den Namen und die Anzahl und Typen der Parameter. Für die JVM ist also eine gleichnamige Methode, die aber einen anderen Parametertyp hat eine völlig getrennte Methode. So funktioniert ja das Überladen von Methoden.Der Fehler gibt hier sogar einen Hinweis auf die Lösung für den Test
t03speed
. Hier habe ich in der Musterlösung nämlich eben das gemacht: Ich habe die Methodemultiply
überladen, indem ich eine weitere, spezifischere Methode gebaut habe, die nur funktioniert, wenn die übergebene Matrix eben auch eineOneDimDoubleMatrix
ist. Dadurch konnte ich dann direkt auf die internen Variablen zugreifen und musste nicht erstget(int)
oderunsafeGet(int)
aufrufen. Jetzt also zurück zum Problem: Beim Kompilieren der Musterlösung auf Dozentron erkennt der Compiler, dass im Test die (spezifischere) MethodeOneDimDoubleMatrix.multiply(OneDimDoubleMatrix)
verwendet werden kann stattOneDimDoubleMatrix.multiply(DoubleMatrix)
und verlinkt diese im Bytecode. Der Fehler, den wir auf Dozentron jetzt machen ist, dass wir den Bytecode der so kompilierten Tests nehmen und ihn mit dem Bytecode Ihrer kompilierten Lösung mischen. Auf Dozentron steht im Bytecode der Tests daher eine Methode, die im Bytecode der Lösung nicht gefunden werden kann, während bei Ihnen lokal die Tests natürlich so kompiliert werden, dass die normale MethodeOneDimDoubleMatrix.multiply(DoubleMatrix)
verlinkt wird und daher läuft auch alles sauber durch.War das irgendwie verständlich? Ich hoffe ja, denn ich finde den Fehler sehr sehr spannend, da er viel über das Zusammenspiel zwischen Quellcode und Bytecode und die statische Typisierung (also das Auflösen von Typen und verlinken von Methoden zur Compilezeit) aussagt. Wenn Sie noch fragen haben, schreiben Sie mir gerne eine Mail. Ich werde auf jeden Fall die Fehlermeldung an Gian weiterreichen.
Long story short: Was müssen wir machen?
- Quellcode von Studis in einen Ordner packen
-
Quellcode der Tests dazupacken
- und ggf. existierende Dateien dabei überschreiben, damit die Studis nicht die Tests oder Interfaces ändern können
- Inhalt gemeinsam kompilieren
- Die so neu kompilierten Tests ausführen