Java JDiagram旧版本在ExtendedArrayList.sort处抛出带有JRE 8的StackOverflower错误
我正在使用JDiagram JAR,如下所示Java JDiagram旧版本在ExtendedArrayList.sort处抛出带有JRE 8的StackOverflower错误,java,arraylist,collections,java-8,default-method,Java,Arraylist,Collections,Java 8,Default Method,我正在使用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.ExtendedArr
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反编译代码。观察到RouteAllinks()在另一个对象(比如router)上调用RouteLink(),并在一个更高的级别上调用出现在错误堆栈跟踪中的deep ExtendeArrayList.sort()。JDiagram中的“ExtendedArrayList”扩展了ArrayList,并包含一个名为“sort()”的方法,该方法具有以下定义
public void sort(Comparator<? super T> paramComparator)
{
Collections.sort(this, paramComparator);
}
public void sort(Comparator我用一个基本示例再现了您的问题:
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
public class ExtendedArrayList<E> extends ArrayList<E> {
@Override
public void sort(Comparator<? super E> c) {
Collections.sort(this, c);
}
}
import java.util.Arrays;
public class Main {
public static void main(String[] args) throws Exception {
ExtendedArrayList<String> arrayList = new ExtendedArrayList<String>();
arrayList.addAll(Arrays.asList("z", "y", "x"));
arrayList.sort(String::compareTo); // -> java.lang.StackOverflowError
}
}
我没有尝试使用您的JDiagram
版本,因为我在他们的网站上只获得了最后一个(与Java 8兼容)版本。考虑反编译库并自行解决问题。您可以使用此固定包作为解决方法
另一种方法是在代码中放置类的固定版本
com.mindfusion.common.ExtendedArrayList
也许你必须配置类加载器来加载你的类,而不是先在库中查找错误的类。选择“父类优先”或在调用库之前从代码中访问类一次都可以解决问题。我发现你的程序的加载不受你的控制。
执行以下步骤:
包括程序的jar(javassist),它可以将“sort”
方法名称更改为任何其他名称,从而避免重写排序方法
通过程序主方法开头的反射class.forName(“”;
)加载jar的(javassist)主类
调用jar的(javassist)方法来对这些方法执行所需的更改
通过这种方式,您可以确保任何jar(javassist)都已加载并准备好使用。哪个代码正在调用sort
、您的应用程序还是库?Holger,感谢您的帮助。.库(JDiagram)正在内部调用sort()方法。因为JAVA 8引入了sort()方法和委托的集合中的。sort()到arraylist排序方法,然后是库排序()变成重写并导致递归…希望它能澄清…非技术性选项:让JDiagram的人在你使用的版本中用sortJ7方法重新编译他们的代码。Assylias:如果可能的话,我不会在这里提出问题!!JDiagram是一个许可的api,获得补丁或升级需要更多的时间时间。我们快发布了,没有足够的时间来完成升级的所有法律程序。顺便说一句,我们已经开始与经理讨论,以便我们可以升级到下一个版本。如果您有任何其他解决方案,请提出。谢谢。在您获得更新的JDiagram之前,我会犹豫是否使用Java 8库。如果Java 8中确实存在一些漏洞,那么可能会有更多的漏洞。此外,如果这是一个获得许可的专有库,任何类型的黑客方法,甚至你所做的反编译都可能违反他们的许可。谢谢。我还没有试过javassist。你能告诉我它是否也使用了一些javaagent或一些类似于AspectJ编织的东西,它涉及自定义类加载。因为正如我所提到的,我们的类是在运行时加载的。而且ExtendeArrayList是由JDiagram而不是我的代码实例化的。同时,我将尝试您的代码并更新线程。再次感谢!!还有一个疑问,Javassist是否也能在模糊JAR上工作?Javassist运行吗没有任何代理,它只是一个库。我不知道模糊处理是否会改变行为。我可以用自己的main()方法修复示例程序中的stackoverflow。但是,我的项目应用程序引发以下异常:javassist.NotFoundException:com.mindfusion.common.ExtendedArrayList at javassist.ClassPool.get(ClassPool.java:450)显然,这是因为这样,我们的项目应用程序加载类。正如我在问题陈述中提到的,AspectJ不能为我工作,因为我们在运行时由另一个组件加载我们的类。然而,我发现Javassist是最好的方法,因为它不涉及任何javagent.thxI仍在使用g使用Javassist并尝试我的运气。非常感谢。谢谢Peter,但是这是一个许可库,它将被视为一个漏洞。此外,JAR是模糊的,因此无法替换sort()的所有引用。好的,Rahul,我理解。但是第二种选择(在您的代码库中用固定版本替换该类)不会吗是否仍然是有效选项?您必须找出类的模糊名称,然后将其放入代码中。不确定class.forName()是否可以替换已加载的类。到目前为止,javassist是最好的方法,但JDiagram混淆会妨碍解决方案正常工作。我理解您的答案,但没有详细说明我的评论。我可以在程序中获取javassist jar类。但使用javassist或任何此类jar,我无法拦截JDiagram类,因为它是模糊的,我们无法控制加载JDiagram的方式。如果它是一个许可的jar,这意味着你已经为它付费,那么他们必须提供支持,我认为如果你问他们并向他们解释情况,他们会根据你的需要更改代码。我请你仔细阅读我的问题,其他答案和评论也会被删除在评论之前。非常感谢您的帮助。我已经阅读了您的问题,因此如果您正在升级jar,那么您将已经更改了方法排序,因此您将不再需要javassist,只是说,不需要再研究这一部分并浪费您的时间。
com.mindfusion.common.ExtendedArrayList