如何调试在Java 7下工作但在Java 8下工作的东西

chi*_*ity 6 java unit-testing phoenix java-7 java-8

我有一个单元测试的项目在Java 7下运行,但不在Java 8下.有没有一种很好的方法来调查这些东西?(我确信测试是正确的;这表明实现中存在一个微妙的错误.)

真的,我想我想要的是一种快速识别代码路径分歧的方法.但这很难,因为通过JDK在代码路径中可能存在非常低级别的各种差异,并且我不希望陷入无关紧要的差异,这些差异归结为微小的优化.

所以,好的方法可能是询问路径偏离的顶级跟踪; 然后,从那一点开始,询问在哪个二级跟踪路径发散; 等等.

但我不知道是否有办法做到这一点.如果我没有系统的方法,我担心我会浪费很多时间.

顺便说一句,代码是Apache Phoenix存储库,在Java 8下,我遇到以下故障:

Tests run: 1, Failures: 1, Errors: 0, Skipped: 0, Time elapsed: 0.006 sec <<< FAILURE! - in org.apache.phoenix.schema.PMetaDataImplTest
testEviction(org.apache.phoenix.schema.PMetaDataImplTest)  Time elapsed: 0.006 sec  <<< FAILURE!
java.lang.AssertionError: expected:<3> but was:<2>
    at org.junit.Assert.fail(Assert.java:88)
    at org.junit.Assert.failNotEquals(Assert.java:834)
    at org.junit.Assert.assertEquals(Assert.java:645)
    at org.junit.Assert.assertEquals(Assert.java:631)
    at org.apache.phoenix.schema.PMetaDataImplTest.testEviction(PMetaDataImplTest.java:98)
Run Code Online (Sandbox Code Playgroud)

dim*_*414 4

Java 7 和 Java 8 之间最明显的变化之一是哈希数据结构处理冲突方式的变化- 以前使用链表,现在条目存储在平衡树中。在某些情况下,这可能会影响这些数据结构的迭代顺序。这不是语言回归,因为这些数据结构明确没有指定迭代顺序,但很容易编写粗心的代码和测试来假定某种顺序。

HashMap在极少数情况下,此更改可能会导致和的迭代顺序发生变化HashSet。没有指定特定的迭代顺序HashMap对象指定特定的迭代顺序 - 任何依赖于迭代顺序的代码都应该被修复。

~ Java SE 8 中集合框架的增强

因此,在调试 Java 7 -> 8 失败时我要做的第一件事就是查找 、 和 的HashMapHashSetConcurrentHashMap。一旦发现错误,您就有几个选择:

  • 将数据结构替换为显式提供迭代顺序的数据结构,例如LinkedHashMapTreeMapImmutableMap
  • 从生产代码中删除迭代顺序假设(例如假设某个键/值将是映射中的第一个元素)。
  • 改进您的测试以实际检查指定的行为(哪些元素)而不是未指定的行为(什么顺序)。通常,测试数据会以易于编写但不正确的方式定义,例如使用内联数组语法int[] expected = {1,2,3},然后循环遍历元素。ImmutableSet.of(1,2,3)您可以使用 Guava 的静态构造函数 ( ) 或Truth的流畅断言语法 ( )来简化此操作assertThat(someSet).containsExactly(1, 2, 3)

如果哈希排序被证明不是根本原因,您的问题可能会更加微妙,并且您的最佳选择可能是按照建议使用调试器单步执行。请务必至少浏览一下JDK 8 中的新增功能以获取线索。