Incompatibility between Java Versions

There is a complex piece of code that performs many complex mathematical operations.

When it is built and tested by maven on jdk 1.7, it passes all the tests. When using jdk 1.8, it fails.

Trying to find a place where the calculations go wrong in the debugger seems almost hopeless.

What are my options? Is there a tool that can scan incompatibility between jdk 1.7 and 1.8 in my code?

Is my best option to run the code in two separate debuggers and see where the difference will be?

EDIT:

@Philipp Claßen This is the most likely reason. I was hoping there would be an automated way to verify this.

@dkatzel The code was not written by me, it is poorly commented and performs scientific calculations, which for me are "woodo".

@ Mike Samuel I do not see the benefits of this approach in running two debuggers in parallel.

Thank you all for your help. It seems that two debuggers are the best way to go.

EDIT 2 The author of the source code relied on streamlining the hash maps. That was the problem.

+5
source share
4 answers

Watch out for sources of non-determinism.

In particular, code based on ordering items in collections such as HashMaps is dangerous because ordering is unspecified and depends on the JVM.

I saw this in every JVM update that such a (buggy) code worked out of luck and immediately worked right after changing the JVM implementation.

+7
source

Adding registration operators to register each intermediate result. You can use something like

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)); } 

Then run it once under Java 7, once under Java 8 and parse the results.

+3
source

It looks like you have a good set of tests that caught the problem. Perhaps a good start would be to compare those tests that pass and those tests that fail. What failed to run tests that are not running?

If the tests that fail do too much, then you need finer-grained tests. Tests should really only check one thing. This means that you should have many tests that test each part of the complex calculation.

Newer versions of Java really try not to break the old working code, so this is hardly a bug in the JDK ... however it is possible ...

+3
source

If there is a specific object that you want to track, and there are not so many points at which the object changes, you can try to set conditional breakpoints that will print information in the .out system instead of continuing Thread. This works great for eclipse, maybe also for other IDEs

For example, to control the value of d at a specific point in the code, you create a breakpoint with the following condition:

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

This condition is never true, but is always evaluated, so it outputs something like this:

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

If this works in your IDE, you can run your program with Java 7 and java 8 in the IDE and compare the output. If you can identify the line in which differences occur, you can continue with normal debugging.

Perhaps you can find more here: http://help.eclipse.org/luna/index.jsp?topic=%2Forg.eclipse.jdt.doc.user%2Ftasks%2Ftask-manage_conditional_breakpoint.htm

0
source

Source: https://habr.com/ru/post/1208916/


All Articles