fallimento Javassist in ibernazione: non valida tipo costante: 60
Domanda
Sto creando uno strumento per gestire i cli un'applicazione esistente. Sia l'applicazione e il test di costruire bene e correre bene, ma nonostante che ricevo un fallimento javassist quando si esegue il mio strumento cli che esiste all'interno della giara:
INFO: Bytecode provider name : javassist
...
INFO: Hibernate EntityManager 3.5.1-Final
Exception in thread "main" javax.persistence.PersistenceException: Unable to configure EntityManagerFactory
at org.hibernate.ejb.Ejb3Configuration.configure(Ejb3Configuration.java:371)
at org.hibernate.ejb.HibernatePersistence.createEntityManagerFactory(HibernatePersistence.java:55)
at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:48)
at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:32)
...
at com.sophware.flexipol.admin.AdminTool.<init>(AdminTool.java:40)
at com.sophware.flexipol.admin.AdminTool.main(AdminTool.java:69)
Caused by: java.lang.RuntimeException: Error while reading file:flexipol-jar-with-dependencies.jar
at org.hibernate.ejb.packaging.NativeScanner.getClassesInJar(NativeScanner.java:131)
at org.hibernate.ejb.Ejb3Configuration.addScannedEntries(Ejb3Configuration.java:467)
at org.hibernate.ejb.Ejb3Configuration.addMetadataFromScan(Ejb3Configuration.java:457)
at org.hibernate.ejb.Ejb3Configuration.configure(Ejb3Configuration.java:347)
... 11 more
Caused by: java.io.IOException: invalid constant type: 60
at javassist.bytecode.ConstPool.readOne(ConstPool.java:1027)
at javassist.bytecode.ConstPool.read(ConstPool.java:970)
at javassist.bytecode.ConstPool.<init>(ConstPool.java:127)
at javassist.bytecode.ClassFile.read(ClassFile.java:693)
at javassist.bytecode.ClassFile.<init>(ClassFile.java:85)
at org.hibernate.ejb.packaging.AbstractJarVisitor.checkAnnotationMatching(AbstractJarVisitor.java:243)
at org.hibernate.ejb.packaging.AbstractJarVisitor.executeJavaElementFilter(AbstractJarVisitor.java:209)
at org.hibernate.ejb.packaging.AbstractJarVisitor.addElement(AbstractJarVisitor.java:170)
at org.hibernate.ejb.packaging.FileZippedJarVisitor.doProcessElements(FileZippedJarVisitor.java:119)
at org.hibernate.ejb.packaging.AbstractJarVisitor.getMatchingEntries(AbstractJarVisitor.java:146)
at org.hibernate.ejb.packaging.NativeScanner.getClassesInJar(NativeScanner.java:128)
... 14 more
Poiché so il vaso è bene come i test di unità e di integrazione eseguite su di esso, ho pensato che potrebbe essere un problema con javassist, così ho provato cglib. Il provider bytecode poi spettacoli come cglib ma ho ancora ottenere la stessa analisi dello stack con il presente javassist in esso.
cglib è sicuramente nel classpath:
$ unzip -l flexipol-jar-with-dependencies.jar | grep cglib | wc -l
383
Ho provato sia con Hibernate 3.4 e 3.5 e ottenere lo stesso errore esatto. È questo un problema con javassist?
Aggiorna : posso eseguire l'applicazione con successo all'interno di Eclipse (click-destro> Esegui As-> Java Application), ma utilizzando l'esperto generati vaso-con-le dipendenze non riesce. Presumo che la differenza è che con Eclipse javassist non sta ispezionando il vaso che contiene, invece, è l'ispezione di tutti i file di classe (e forse un paio di dipendenti barattoli 3rd-party).
Soluzione
Il problema è in ultima analisi, causato da una classe non valida in icu4j-2.6.1
come si può vedere nella questo post . In particolare, questo file non è valido:
com/ibm/icu/impl/data/LocaleElements_zh__PINYIN.class
Ecco un modo semplice per identificare un file danneggiato:
for x in PATH_TO_EXTRACTED_JAR/**/*.class; do
java -cp PATH_TO/javassist.jar javassist.tools.Dump $x >/dev/null 2>&1 || echo "$x is invalid"
done
Questo file sia incluso per indirettamente da Maven attraverso le sue dipendenze transitive è per questo che non ho riconosciuto la pagina come riferimento l'errore e un file contenuto all'interno del vaso come il colpevole e la causa del problema. Ecco come è finito inclusa nel mio vaso-con-dipendenze bundle:
jaxen-1.1.1 -> xom-1.0 -> icu4j-2.6.1
Dopo aver aggiunto il seguente esclusione alla dipendenza jaxen
, tutto ha funzionato correttamente per me (ma attenzione se avete bisogno dei suoi pezzi di localizzazione):
<exclusions>
<exclusion>
<groupId>com.ibm.icu</groupId>
<artifactId>icu4j</artifactId>
</exclusion>
</exclusions>
Un'altra opzione sarebbe quella di rimuovere il file incriminato (s) dal file jar:
#!/bin/sh
shopt -s extglob
shopt -s globstar
for x in **/*.jar ; do
zip -d $x 'com/ibm/icu/impl/data/*_zh*' >/dev/null 2>&1 && echo "Removed corrupted files from $x"
done