2015-05-18 15 views
15

Ho un problema con la libreria Reflections. Sto provando a caricare dinamicamente tutte le classi che implementano un'interfaccia specifica. Tutto funziona correttamente (tutte le classi sono caricate) a condizione che non usi espressioni lambda in queste classi (java 8). Ho provato la versione di aggiornamento della lib ma l'effetto era lo stesso (java.io.IOException: tipo costante non valido: 18).Riflessioni - Java 8 - tipo costante non valido

Dipendenza e costruire in 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> 

senza esclusione è lo stesso effetto.

Codice:

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); 

Come posso caricare le classi con l'espressione lambda?

P.S Spiacente per l'inglese :)

+0

Possibile duplicato di [Errore durante la creazione di entityManagerFactory a causa dell'errore che si lega alla scansione ] (http://stackoverflow.com/questions/24281235/error-creating-entitymanagerfactory-due-to-error-tying-to-scan-jar -file) –

risposta

29

Se si guarda alla this table, vedrete che “tipo costante: 18” fa riferimento all'attributo CONSTANT_InvokeDynamic il cui valore di tag è 18.

Quindi si sta utilizzando una libreria con un parser di classe che non è compatibile con Java 8. In realtà, questo parser di classe non è compatibile con Java 7 in quanto questo valore costante è specificato da Java 7. È stato appena superato con questo, poiché il normale codice Java non utilizza questa funzionalità in Java 7. Ma quando si interagisce con codice prodotto da diversi linguaggi di programmazione per JVM, potrebbe anche fallire con Java 7.

C'è il an item in the bug tracker of Reflections che descrive il tuo problema. Nella parte inferiore, troverete l'avviso:

Con questa correzione: https://issues.jboss.org/browse/JASSIST-174 javassist ha ottenuto il supporto per questa costante. Quindi con 3.18.2-GA questo errore non si verifica.

+2

Ho visto questa soluzione ma ho usato la versione più recente di queste librerie.Alla fine ho rimosso la lib di riflessione e ho scritto la propria riflessione per i sottotipi di classe con la lib di Guava. Grazie per la risposta. – Lukasz

+1

Lo stesso problema qui: ho avuto diverse versioni di javassist in 3 framework (HikariCP, Orika e Swagger-jaxrs) e Maven ha scelto il più vecchio come risoluzione automatica (3.16-1.-GA invece dell'ultima 3.19.0-GA) – Tristan

+1

javassist è anche in bingo powermock – jediz

3

Ho appena risolto un problema simile qui. Nel mio caso, ci sono due vasi javassist sul mio classpath. Uso Maven e dovevo evitarlo, ma una delle dipendenze utilizzava un groupId diverso (javassist per quello vecchio e org.javassist per quello nuovo, importato da org.reflections), quindi Maven le gestiva come artefatti diversi.

Ho appena cambiato la libreria in base alla precedente per dipendere da quella nuova e tutto è stato risolto!

-2

Ho riscontrato questo problema, quindi ho eseguito temporaneamente il downgrade dal mio jdk, EXPORT JAVA_HOME = "/ home/utente/jdk1.7.0_55" e tutto ha funzionato correttamente.

+1

Dovresti considerare tutte le restrizioni nella domanda originale, il downgrade non è davvero una soluzione a qualsiasi problema. – BrunoJCM

0

Se si utilizza weblogic potrebbe essere un conflitto con le librerie già caricate dal suo programma di caricamento classi. È possibile ignorare mettendo

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

nel file di configurazione weblogic.xml dei vostri progetti web. Nota: il vero pacchetto java è solo javassist, non org.javassist (maven groupId).