java版本之间的不兼容性

时间:2014-12-12 19:57:36

标签: java java-8 java-7 incompatibility

有一段复杂的代码可以执行许多复杂的数学运算。

当它由maven在jdk 1.7上构建和测试时,它会通过所有测试。 使用jdk 1.8时失败。

试图在调试器中找到计算出错的地方似乎几乎没有用。

我有什么选择?是否有一个工具可以在我的代码中扫描jdk 1.7和1.8之间的不兼容性?

我最好选择在两个单独的调试器中运行代码,看看差异在哪里?

修改

@PhilippClaßen 到目前为止,这是最可能的原因。我希望有一种自动检查方法。

@dkatzel 这段代码不是我写的,评论很差,并且对我来说是“木头”的科学计算。

@Mike Samuel 我认为这种方法与并行运行两个调试器没有任何好处。

谢谢大家的帮助。似乎两个调试器是最好的方法。

编辑2 原始代码的作者依赖于哈希映射排序。这就是问题所在。

4 个答案:

答案 0 :(得分:7)

留意非确定性的来源。

特别是依赖于像HashMaps这样的集合中元素排序的代码是危险的,因为排序是未指定的并且取决于JVM。

我在每次JVM升级中都看到过这样的(错误的)代码运气好,并且一旦JVM实现发生变化就会立即崩溃。

答案 1 :(得分:3)

添加日志记录语句以记录每个中间结果。你可以使用像

这样的东西
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));
}

然后在Java 7下运行一次,在Java 8下运行一次,并对结果进行区分。

答案 2 :(得分:3)

好像你有一套很好的测试可以解决这个问题。也许一个好的开始是比较通过的测试和失败的测试。失败的测试有何不同?

如果失败的测试做得太多,那么你需要更细粒度的测试。测试应该只是单独测试一件事。这意味着您应该有许多测试来测试复杂计算的每个部分。

Java的新版本确实努力不破坏旧的工作代码,因此它不太可能是JDK中的错误...但是它有可能......

答案 3 :(得分:0)

如果有特定对象,您想要监控并且对象更改的点数不是太多,您可以尝试设置条件断点,这会将信息输出到系统.out而不是代替Thread。这适用于eclipse,也可能适用于其他IDE 例如,要监视特定代码点的值d,可以使用以下条件创建断点:

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

这种情况从来都不是真的,但总是被评估,所以它打印出类似的东西:

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

如果这在您的IDE中有效,您可以在IDE中使用Java 7和Java 8运行程序并比较输出。如果您可以识别出现差异的行,您可以继续进行常规调试。

您可以在此处找到更多信息:http://help.eclipse.org/luna/index.jsp?topic=%2Forg.eclipse.jdt.doc.user%2Ftasks%2Ftask-manage_conditional_breakpoint.htm