kusumotolab / kGenProg

A High-performance, High-extensibility and High-portability APR System
MIT License
48 stars 13 forks source link

jdk12以降でClassLoaderのテストがfail #716

Closed shinsuke-mat closed 4 years ago

shinsuke-mat commented 4 years ago

GitHubActionsによるマトリックステストで発見したバグ. https://github.com/hnymA/kGenProg/pull/3

jdk12以降でjavaネイティブクラスへのreflectionが禁止になった. https://stackoverflow.com/questions/56039341/get-declared-fields-of-java-lang-reflect-fields-in-jdk12

MemoryClassLoaderTestではクラスローダがロードしたクラス一覧のテストを行っているが, クラス一覧の取得に以下リフレクションを使っている.

  private List<String> listLoadedClasses(final ClassLoader classLoader) throws Exception {
    final Class<?> javaLangClassLoader = findJavaLangClassLoader(classLoader.getClass());

    // ↓これ
    final Field classesField = javaLangClassLoader.getDeclaredField("classes");

このリフレクションに失敗する.

java.lang.NoSuchFieldException: classes

    at java.base/java.lang.Class.getDeclaredField(Class.java:2412)
    at jp.kusumotolab.kgenprog.project.test.MemoryClassLoaderTest.listLoadedClasses(MemoryClassLoaderTest.java:260)
    at ...
shinsuke-mat commented 4 years ago

javaの機能として禁止になったので,実装を直すしかない. 幸いテストの一部の問題かつ,自前クラスローダへのリフレクションの問題である. よって自前クラスローダ(MemoryClassLoader)に,ロード済みクラス一覧の確認APIを作ればよい.

shinsuke-mat commented 4 years ago

上記間違ってる. x 自前クラスローダへのリフレクションの問題である. o java.lang.ClassLoaderへのリフレクションの問題である.

どうすんねんこれ. ClassLoaderのテストはとても難しい.

shinsuke-mat commented 4 years ago

案1

https://stackoverflow.com/questions/56039341/get-declared-fields-of-java-lang-reflect-fields-in-jdk12 リフレクションを使いつつ,これのhackを使う. cons: 12.0.1以降でも動く保証がない. セキュリティの問題を抱える.

案2

リフレクションを使わないように変更する. 理想はこれ. cons: やり方が思いつかない

案3

当該テストを削除する. cons: 当該テストはそれなりに重要で,残しておきたい

案4

jdk12以降だけ,当該テストをスキップする.