Отражения - 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);

Как я могу загружать классы с выражением лямбда?

P.S Извините за английский:)

Ответы

Ответ 1

Если вы посмотрите на эту таблицу, вы увидите, что "постоянный тип: 18" относится к CONSTANT_InvokeDynamic, значение тега которого 18.

Итак, вы используете библиотеку с парсером класса, не совместимым с Java 8. На самом деле, этот парсер классов даже не совместим с Java 7, поскольку это постоянное значение задано с Java 7. Это просто ушло с тем, что, поскольку обычный Java-код не использует эту функцию в Java 7. Но при взаимодействии с кодом, созданным разными языками программирования для JVM, он может даже сбой с Java 7.

Theres элемент в описании треков отражений, описывающий вашу проблему. Внизу вы найдете уведомление:

С этим исправлением: https://issues.jboss.org/browse/JASSIST-174 javassist получил поддержку этой константы. Таким образом, с 3.18.2-GA эта ошибка не возникает.

Ответ 2

Я просто установил аналогичную проблему здесь. В моем случае на моем классовом пути было два javassist jars. Я использую maven, и это должно было избежать этого, но в одной из зависимостей использовалась другая groupId (javassist для старой и org.javassist для новой, импортированной org.reflections), поэтому maven обрабатывал их как разные артефакты.

Я просто изменил библиотеку в зависимости от старой, чтобы зависеть от новой, и все исправлено!

Ответ 3

Я решил эту проблему;

Первый апгрейд javassist до → 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>

Ответ 4

Если вы используете weblogic, это может быть конфликт с библиотеками, уже загруженными им загрузчиком классов. Вы можете переопределить их, поставив

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

в конфигурационных файлах weblogic.xml веб-проектов. Обратите внимание, что реальный пакет java - это просто javassist, а не org.javassist (maven groupId).

Ответ 5

У меня была эта проблема, поэтому я временно отказался от моего jdk, EXPORT JAVA_HOME = "/home/user/jdk1.7.0_55" и все работало нормально.