Javassist Versagen in Hibernate: ungültiger Konstante Typ: 60
Frage
Ich erstelle ein cli-Tool eine bestehende Anwendung zu verwalten. Sowohl die Anwendung und die Tests Build Fein- und läuft gut, aber trotz, dass ich wirklich einen Javassist Fehler, wenn mein cli Werkzeug ausgeführt wird, die im Glas vorhanden ist:
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
Da ich das Glas ist in Ordnung, die Einheit und Integrationstests liefen dagegen wissen, dachte ich, es könnte ein Problem mit Javassist sein, so dass ich cglib versucht. Die Bytecode-Provider dann zeigt als cglib aber ich hat noch genau die gleichen Stack-Trace mit Javassist in ihm.
cglib ist auf jeden Fall in der Classpath:
$ unzip -l flexipol-jar-with-dependencies.jar | grep cglib | wc -l
383
Ich habe versucht, sowohl mit Hibernate 3.4 und 3.5 und die exakt gleichen Fehlern. Ist das ein Problem mit Javassist?
UPDATE : Ich habe die Anwendung erfolgreich innerhalb von Eclipse (rechte Maustaste> Ausführen As-> Java Application), aber mit der Maven-generierte jar-with-Abhängigkeiten führen kann fehlschlägt. Ich nehme an der Unterschied ist, dass mit Eclipse Javassist nicht enthalten Glas inspiziert, sondern es ist alles der Klassendateien (und vielleicht ein paar abhängig 3rd-Party-Gläser) inspizieren.
Lösung
Das Problem wird schließlich durch eine ungültige Klasse in icu4j-2.6.1
verursacht wie in diesem Beitrag gesehen werden . Insbesondere diese Datei ist ungültig:
com/ibm/icu/impl/data/LocaleElements_zh__PINYIN.class
Hier ist eine einfache Möglichkeit, eine beschädigte Datei zu identifizieren:
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
Diese Datei enthält, indem indirekt über ihre transitiven Abhängigkeiten von Maven wird, weshalb ich diese Seite nicht als Verweis auf die Fehler erkannt habe und eine im Glas enthaltenen Datei als der Täter und die Ursache des Problems zu sein. Hier ist, wie es oben endete in meinem enthalten jar-with-Abhängigkeiten bündeln:
jaxen-1.1.1 -> xom-1.0 -> icu4j-2.6.1
Nach dem Hinzufügen der folgenden Ausschluss der jaxen
Abhängigkeit, hat alles für mich richtig (aber vorsichtig sein, wenn man seine Lokalisierung Stücke müssen):
<exclusions>
<exclusion>
<groupId>com.ibm.icu</groupId>
<artifactId>icu4j</artifactId>
</exclusion>
</exclusions>
Eine andere Möglichkeit wäre es, die betroffene Datei (en) aus der JAR-Datei zu entfernen:
#!/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