我正在使用 JDiagram JAR,如下所示
Diagram myDigram = new Diagram();
myDigram.routeAllLinks();
此代码在使用 JRE 7 运行时运行良好,但是在使用 JRE 8 运行时,会引发以下错误:
java.lang.StackOverflowError
at java.util.Collections.sort(Unknown Source)
at com.mindfusion.common.ExtendedArrayList.sort(Unknown Source)
at java.util.Collections.sort(Unknown Source)
at com.mindfusion.common.ExtendedArrayList.sort(Unknown Source)
at java.util.Collections.sort(Unknown Source)
at com.mindfusion.common.ExtendedArrayList.sort(Unknown Source)
我按照堆栈跟踪到 JDiagram 反编译代码。观察到 routeAllLinks() 在另一个对象(例如路由器)上调用 RouteLinks() ,并且在更深一层上调用了出现在错误堆栈跟踪中的 ExtendedArrayList.sort()。JDiagram 中的“ExtendedArrayList”扩展了 ArrayList 并包含一个名为“sort()”的方法,该方法具有以下定义。
public void sort(Comparator<? super T> paramComparator)
{
Collections.sort(this, paramComparator);
}
在 Google 上,我发现 JRE 8 引入了 List.sort() 并将 Collections.sort() 调用委托给集合的(在我的情况下为 ExtendedArrayList)排序方法。所以库 ExtendedArrayList.sort() 变成了一个覆盖。它创建了一个无限递归,导致stackoverflow。我现在也可以用一小段代码重现这个问题。
还
- 我们创建 JDiagram 对象的原始类在运行时由我们产品中的其他一些组件加载。我们对程序的加载几乎没有控制权。
- 我们发现最新版本的 JDiagram 已通过将 sort() 替换为 sortJ7() 方法来解决此问题。但是,我们目前无法升级库。JDiagram 是一个许可的 API。
- ExtendedArrayList 在内部由 JDiagram 实例化,因此我们无法从代码中更改它。
我们尝试了以下迄今为止不起作用的解决方案
- Java 代理:因为我们的代码没有直接调用 ExtendedArrayList,而且 'Diagram' 也没有任何接口。
- Spring AOP:我们没有使用 spring,而且我们的程序是由其他组件在运行时加载的。
- AspectJ:到目前为止,这显然是一个解决方案。但是,它也不起作用,因为我们无法在运行时编织我们的程序。不确定是否有人可以使它工作。
请让我知道是否需要详细说明。欢迎任何帮助。谢谢。
更新 到目前为止,javassist 是最好的方法,但是 JDiagram 混淆会阻止解决方案正常工作。考虑到我们的发布日期,我们有点假设不可能(不得不说)修复。我们已经开始升级库的过程。同时从我们的应用程序中删除了一个由 routeAllLinks() 方法提供的小功能.. :-( 感谢大家的帮助。我将继续研究这个问题,因为我发现它非常有趣和具有挑战性.. 我'如果我能解决它,我会更新这篇文章。我会为@gontard 的 javassist 方法提供赏金,因为我正在继续我的研究。谢谢。