以下のように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() を呼び出し、さらに 1 つ深いレベルで、エラー スタック トレースに表示される 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() がオーバーライドになりました。そして、スタックオーバーフローを引き起こす無限再帰を作成します。小さなコードでもこの問題を再現できました。
また
- JDiagram オブジェクトを作成する元のクラスは、製品の他のコンポーネントによって実行時にロードされます。プログラムのロードをほとんど制御できません。
- JDiagram の最新バージョンでは、sort() メソッドを sortJ7() メソッドに置き換えることでこの問題が修正されていることがわかりました。ただし、現時点ではライブラリをアップグレードできません。JDiagram はライセンスされた API です。
- ExtendedArrayList は JDiagram によって内部的にインスタンス化されているため、コードから変更することはできません。
これまでに機能しなかった次のソリューションを試しました
- Java プロキシ: 私たちのコードは ExtendedArrayList を直接呼び出さず、'Diagram' にはインターフェイスがないためです。
- Spring AOP: Spring を使用しておらず、プログラムは他のコンポーネントによって実行時に読み込まれます。
- AspectJ: 今では、これは明らかに解決策でした。ただし、実行時にプログラムを織り込むことができないため、これも機能しませんでした。誰かがそれを機能させることができるかどうかはわかりません。
補足が必要な点があれば教えてください。どんな助けでも大歓迎です。ありがとう。
更新 これまでのところ、javassist が最良のアプローチですが、JDiagram の難読化により、ソリューションが正しく機能しません。私たちは、リリース日を頭の中で考えると、修正することは不可能 (と言わざるを得ない) であると想定しています。ライブラリをアップグレードするプロセスを開始しました。その間、routeAllLinks() メソッドによって提供されていたアプリケーションから小さな機能を削除しました.. :-( 皆さんの助けに感謝します. この問題は本当に興味深く、挑戦的であることがわかったので、この問題に関する研究を続けます.. 「解決できたら投稿を更新します..そして、研究を続けているので、@gontard の javassist アプローチに対して報奨金を与えます.ありがとう.