échec javassist en veille prolongée: type constante invalide: 60
Question
Je crée un outil cli pour gérer une application existante. L'application et les tests de construction fine fin et course mais malgré que je reçois un échec de javassist lors de l'exécution de mon outil cli qui existe dans le pot:
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
Depuis que je sais que le pot est bien que les tests unitaires et d'intégration se présenter contre, je pensais que ce serait peut-être un problème avec javassist, alors j'ai essayé cglib. Le fournisseur de bytecode montre ensuite que cglib mais je reçois toujours exactement la même trace de la pile avec javassist présente en elle.
cglib est sans aucun doute dans le classpath:
$ unzip -l flexipol-jar-with-dependencies.jar | grep cglib | wc -l
383
Je l'ai essayé à la fois mise en veille prolongée 3.4 et 3.5 et obtenir exactement la même erreur. Est-ce un problème avec javassist?
UPDATE : Je peux exécuter l'application avec succès dans Eclipse (droit droit-> Exécuter As-> Java Application), mais en utilisant le pot avec dépendances générées maven-échoue. Je présume que la différence est que, avec Eclipse javassist n'est pas inspectait le pot contenant, plutôt, il est l'inspection de tous les fichiers de classe (et peut-être quelques pots 3 parties à charge).
La solution
Le problème est finalement causé par une classe non valide dans icu4j-2.6.1
comme on peut le voir dans ce message . Plus précisément, ce fichier est incorrect:
com/ibm/icu/impl/data/LocaleElements_zh__PINYIN.class
Voici un moyen simple d'identifier un fichier corrompu:
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
Ce fichier est inclus par indirectement par Maven par ses dépendances transitif qui est la raison pour laquelle je ne reconnaissais pas cette page comme référence à l'erreur et un fichier contenu dans le pot comme étant le coupable et la cause du problème. Voici comment il a fini inclus dans mon pot-avec-dépendances bundle:
jaxen-1.1.1 -> xom-1.0 -> icu4j-2.6.1
Après avoir ajouté l'exclusion suivante à la dépendance jaxen
, tout a fonctionné correctement pour moi (mais attention si vous avez besoin de ses pièces de localisation):
<exclusions>
<exclusion>
<groupId>com.ibm.icu</groupId>
<artifactId>icu4j</artifactId>
</exclusion>
</exclusions>
Une autre option serait de supprimer le fichier incriminé (s) à partir du fichier 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