web-dev-qa-db-ja.com

リフレクション-Java 8-無効な定数タイプ

Reflections ライブラリに問題があります。特定のインターフェイスを実装するすべてのクラスを動的にロードしようとしています。これらのクラスでラムダ式を使用しない限り、すべてが正常に機能します(すべてのクラスがロードされます)(Java 8)。 libバージョンをアップグレードしようとしましたが、効果は同じでした(Java.io.IOException:無効な定数タイプ:18)。

依存関係とpom​​.xmlのビルド

      <dependency>
        <groupId>org.reflections</groupId>
        <artifactId>reflections</artifactId>
        <version>0.9.10</version>
        <exclusions>
            <exclusion>
                <groupId>javassist</groupId>
                <artifactId>javassist</artifactId>
            </exclusion>
        </exclusions>
    </dependency>

    <dependency>
        <groupId>org.javassist</groupId>
        <artifactId>javassist</artifactId>
        <version>3.19.0-GA</version>
    </dependency>
    <build>
    <plugins>
        <plugin>
            <groupId>org.Apache.maven.plugins</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
            <configuration>
                <source>1.8</source>
                <target>1.8</target>
            </configuration>
        </plugin>
    </plugins>
    </build>

除外せずに同じ効果です。

コード:

    URL jarUrl = jarFile.toURI().toURL();
    URLClassLoader child = new URLClassLoader(new URL[]{jarUrl}, this.getClass().getClassLoader());
    ConfigurationBuilder builder = new ConfigurationBuilder()
            .addClassLoader(child)
            .addUrls(jarUrl)
            .setScanners(new SubTypesScanner());
    Reflections r = new Reflections(builder);
    return r.getSubTypesOf(cls);

ラムダ式でクラスをロードするにはどうすればよいですか?

追伸:英語でごめんなさい:)

22
Lukasz

この表 を見ると、「定数タイプ:18」は、タグ値がCONSTANT_InvokeDynamicである 18 属性を参照していることがわかります。 。

そのため、Java 8互換ではないクラスパーサーを備えたライブラリを使用しています。実際、この定数値はJava 7以降に指定されているため、このクラスパーサーはJava 7にも対応していません。通常のJavaコードはJava 7でこの機能を使用しません。しかし、JVM用のさまざまなプログラミング言語で作成されたコードを操作する場合、Java 7で失敗することさえあります。

Reflectionのバグトラッカーの項目 問題を説明しています。下部に、通知があります。

この修正により: https://issues.jboss.org/browse/JASSIST-174 javassistはこの定数をサポートしました。したがって、3.18.2-GAでは、このエラーは発生しません。

37
Holger

私はこの問題を解決しました;

最初にjavassist jarを-> 3.18.2-GAにアップグレードします

  <dependency>
    <groupId>org.javassist</groupId>
    <artifactId>javassist</artifactId>
    <version>3.18.2-GA</version>
  </dependency>

次に、weblogic.xmlを追加します

 <wls:package-name>javassist.*</wls:package-name>
8
mehmetunluu

ここで同様の問題を修正しました。私の場合、クラスパスには2つのjavassist jarがありました。私はmavenを使用していますが、それを回避することになっていますが、依存関係の1つが異なるgroupId(古いものにはjavassistorg.javassistは、org.reflections)、mavenはそれらを異なるアーティファクトとして処理しました。

古いライブラリを新しいライブラリに依存するようにライブラリを変更したところ、すべてが修正されました!

7
BrunoJCM

Weblogicを使用する場合、クラスローダーによって既にロードされているライブラリと競合する可能性があります。あなたはそれらをオーバーライドすることができます

...
<weblogic-web-app>
    <container-descriptor>
        <prefer-application-packages>
            <package-name>javassist.*</package-name>
...

webプロジェクトのweblogic.xml設定ファイル。実際のJavaパッケージはorg.javassist(maven groupId)ではなくjavassistであることに注意してください。

0
jediz

Websphereでは、アプリケーションでパッケージ化されたJARがサーバーによって提供されるJARよりも優先されるように、そのアプリケーションの「最後の親」クラスローダーを有効にすることで問題を解決しました。

0
Pino