Отражения - 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" и все работало нормально.