J'ai un problème avec Reflections library . J'essaie de charger dynamiquement toutes les classes qui implémentent une interface spécifique . Tout fonctionne correctement (toutes les classes sont chargées) tant que je n'utilise pas d'expression lambda dans ces classes (Java 8) . J'ai essayé de mettre à niveau la version lib mais l’effet était identique (Java.io.IOException: type de constante non valide: 18).
Dépendance et construction dans 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>
sans exclusion est le même effet.
Code:
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);
Comment puis-je charger des classes avec l'expression lambda?
P.S Désolé pour l'anglais :)
Si vous regardez ce tableau , vous verrez que «type constant: 18» fait référence à CONSTANT_InvokeDynamic
attribut dont la valeur de balise est 18
.
Vous utilisez donc une bibliothèque dont l’analyseur de classe n’est pas compatible avec Java 8. En réalité, cet analyseur de classe n'est même pas compatible avec Java 7, car cette valeur constante est spécifiée depuis Java 7. Il s'en tire comme cela, car le code Java ordinaire n'utilise pas cette fonctionnalité dans Java 7. Mais lors de l'interaction avec du code produit par différents langages de programmation pour la machine virtuelle Java, il pourrait même échouer avec Java 7.
Il y a un élément dans le suivi des bogues de Reflections décrivant votre problème. En bas, vous trouverez la notice:
Avec ce correctif: https://issues.jboss.org/browse/JASSIST-174 javassist a obtenu le support pour cette constante. Donc, avec 3.18.2-GA, cette erreur ne se produit pas.
Je viens de résoudre un problème similaire ici. Dans mon cas, il y avait deux jarres javassistes sur mon parcours. J'utilise maven et c'était supposé éviter cela, mais l'une des dépendances utilisait un ID de groupe différent (javassist
pour l'ancien et org.javassist
pour le nouveau, importé par org.reflections
). Maven les traitait donc comme des artefacts différents.
Je viens de changer la bibliothèque en fonction de l’ancienne bibliothèque. Tout est réparé!
J'ai résolu ce problème
Première mise à niveau du fichier javassist
vers -> 3.18.2-GA
<dependency>
<groupId>org.javassist</groupId>
<artifactId>javassist</artifactId>
<version>3.18.2-GA</version>
</dependency>
Deuxièmement, ajoutez weblogic.xml
<wls:package-name>javassist.*</wls:package-name>
Si vous utilisez weblogic, cela peut être un conflit avec les bibliothèques déjà chargées par son chargeur de classes. Vous pouvez les remplacer en mettant
...
<weblogic-web-app>
<container-descriptor>
<prefer-application-packages>
<package-name>javassist.*</package-name>
...
dans le fichier de configuration weblogic.xml
de vos projets Web. Notez que le vrai package Java est simplement javassist
, pas org.javassist
(maven groupId).
Sur Websphere, j'ai résolu le problème en activant le chargeur de classe "dernier parent" pour cette application, de sorte que les fichiers JAR fournis avec l'application aient priorité sur ceux fournis par le serveur.