2014-12-12 18 views
5

Es gibt einen komplexen Code, der viele komplexe mathematische Operationen ausführt.Inkompatibilitäten zwischen Java-Versionen

Wenn es von maven auf jdk 1.7 gebaut und getestet wird, besteht es alle Tests. Bei Verwendung von jdk 1.8 schlägt es fehl.

Der Versuch, die Stelle zu finden, an der die Berechnungen in einem Debugger schiefgehen, erscheint fast hoffnungslos.

Was sind meine Optionen? Gibt es ein Tool, das in meinem Code nach Inkompatibilitäten zwischen jdk 1.7 und 1.8 suchen kann?

Ist meine beste Option, den Code in zwei separaten Debuggern auszuführen und zu sehen, wo der Unterschied wäre?

EDIT:

@Philipp Claßen , dass die wahrscheinlichste Ursache ist so weit. Ich hatte gehofft, dass es einen automatisierten Weg dafür geben würde.

@dkatzel Der Code wurde nicht von mir geschrieben, schlecht kommentiert und macht wissenschaftliche Berechnungen, die "Woodo" für mich sind.

@Mike Samuel Ich sehe keinen Vorteil dieses Ansatzes gegenüber dem Ausführen von zwei Debuggern parallel.

Vielen Dank für Ihre Hilfe. Scheint, dass zwei Debugger der beste Weg zu gehen ist.

EDIT 2 Der Autor des ursprünglichen Codes war auf Hash-Map-Reihenfolge angewiesen. Das war das Problem.

+0

Überprüfen Sie die Release Notes für Hinweise. Ansonsten denke ich, dass Sie zwei Debugger ausführen müssen. –

+1

können Sie bitte etwas Code posten? –

+0

Ich kann garantieren, dass Seeing-Code nicht hilft. Es sei denn, Sie möchten Tausende von Zeilen durchlaufen. – Andrey

Antwort

3

Fügen Sie Protokollierungsanweisungen hinzu, um jedes Zwischenergebnis zu protokollieren. Anschließend können Sie es einmal 7 unter Java so etwas wie

static void dumpDoubleWithLineNumber(double d) { 
    StackTraceElement[] stack = Thread.currentThread().getStackTrace(); 
    // Thread.getStackTrace() and this method are elements 0 and 1 
    StackTraceElement caller = stack[2]; 
    System.err.println(
     caller.toString() 
     + " : " + d 
     + "/" + Long.toString(Double.toLongBits(d), 16)); 
} 

verwenden, einmal unter Java 8 und die Ergebnisse diff.

+0

Es tut mir leid, aber angesichts der Tatsache, dass er bereits Testfälle hat, und der Code ist 1000s Zeilen, ist das nicht ein wenig Hello World Ansatz? Ich würde lieber mit Testfällen und deren Stack-Traces beginnen. – Shaunak

+0

@Shaunak, Ich weiß nicht, was ein Hello World-Ansatz ist, aber die Test-Stack-Traces sagen nur, wo der Fehler entdeckt wurde. Ein Diff von Protokollen von einem fehlgeschlagenen Test wird Ihnen sagen, wo die Divergenz begonnen hat. 1000 Linien sind ein ziemlich kleines Programm. Ein paar hundert Log-Statements einzutragen, sollte 20 Minuten dauern. Der Versuch, von einem Testfehler rückwärts zu denken, kann Stunden oder Tage dauern. –

+0

Genau das, wofür wir Testfälle schreiben! und sieht so aus, als hätte er bereits eine gute Menge von Testfällen, die das Problem auffingen. – Shaunak

3

Scheint wie Sie eine gute Reihe von Tests haben, die das Problem erwischt. Vielleicht wäre ein guter Anfang, die Tests zu vergleichen, die bestehen und die Tests, die ausfallen. Was haben die fehlgeschlagenen Tests anders gemacht?

Wenn die Tests, die fehlschlagen, zu viel tun, dann benötigen Sie mehr feinkörnige Tests. Tests sollten wirklich nur eine Sache isoliert testen. Dies bedeutet, dass Sie viele Tests haben sollten, die jeden Teil der komplexen Berechnung testen.

Neue Versionen von Java versuchen wirklich schwer, nicht alten Arbeits Code zu brechen, so dass es ein Fehler im JDK unwahrscheinlich ist ... aber es möglich ist, ...

+0

Nun, das ist ein besserer Weg zu beginnen .. – Shaunak

7

für Quellen von Nicht-Determinismus Halten Sie Ausschau.

Insbesondere Code, der auf der Anordnung von Elementen in Sammlungen wie HashMaps beruht, ist gefährlich, da die Reihenfolge nicht angegeben ist und von der JVM abhängt.

Ich habe es in jedem JVM-Upgrade gesehen, dass solcher (buggy) Code von Glück funktioniert hat und sofort brach, nachdem sich die JVM-Implementierung geändert hat.

0

Wenn ein bestimmtes Objekt ist, soll überwacht werden und die Punkte, wo sich das Objekt geändert wird, sind nicht zu viele, könnten Sie versuchen bedingte Haltepunkte festlegen, welche Informationen zu System.out aus gedruckt werden statt den Thread aufhängen. Das funktioniert gut für Eclipse, kann auch
Zum Beispiel für andere IDEs sein, den Wert d an einer bestimmten Stelle des Codes zu überwachen, können Sie einen Haltepunkt mit der folgenden Bedingung erstellen:

System.out.println(Thread.currentThread().getStackTrace()[1] + " value="+d); return false; 

Diese Bedingung ist nie wahr, aber immer ausgewertet, so druckt es so ähnlich aus:

test.Main.main(Main.java:23) value=1.0 

Wenn dies in Ihrem IDE funktioniert, können Sie Ihr Programm mit Java 7 und Java 8 in der IDE und Vergleichen der Ausgabe ausgeführt werden können. Wenn Sie die Linie identifizieren können, in der die Unterschiede auftreten, können Sie mit dem herkömmlichen Debugging fortfahren.

Mai werden Sie mehr finden Sie hier: http://help.eclipse.org/luna/index.jsp?topic=%2Forg.eclipse.jdt.doc.user%2Ftasks%2Ftask-manage_conditional_breakpoint.htm

Verwandte Themen