web-dev-qa-db-fra.com

Problème de classe Jackson Databind

J'ai une application de démarrage de printemps qui fonctionne bien lorsque je fais le déploiement en utilisant "mvn clean install" dans mon local, mais lorsque la guerre est générée par Jenkin, il jette l'erreur suivante.

Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'objectMapper' defined in class path resource [com/test/common/TestRestConfiguration.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [com.fasterxml.jackson.databind.ObjectMapper]: Factory method 'objectMapper' threw exception; nested exception is Java.lang.NoClassDefFoundError: Could not initialize class com.fasterxml.jackson.databind.SerializationConfig
        at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.Java:599)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.Java:1123)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.Java:1018)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.Java:510)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.Java:482)
        at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.Java:306)
        at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.Java:230)
        at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.Java:302)
        at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.Java:197)
        at org.springframework.beans.factory.support.DefaultListableBeanFactory.findAutowireCandidates(DefaultListableBeanFactory.Java:1192)
        at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.Java:1116)
        at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.Java:1014)
        at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.Java:545)
        ... 62 common frames omitted
Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [com.fasterxml.jackson.databind.ObjectMapper]: Factory method 'objectMapper' threw exception; nested exception is Java.lang.NoClassDefFoundError: Could not initialize class com.fasterxml.jackson.databind.SerializationConfig
        at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.Java:189)
        at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.Java:588)
        ... 74 common frames omitted
Caused by: Java.lang.NoClassDefFoundError: Could not initialize class com.fasterxml.jackson.databind.SerializationConfig
        at com.fasterxml.jackson.databind.ObjectMapper.<init>(ObjectMapper.Java:535)
        at com.fasterxml.jackson.databind.ObjectMapper.<init>(ObjectMapper.Java:452)

J'ai juste essayé de comparer les 2 fichiers de guerre en utilisant au-delà de la comparaison et je ne vois aucune différence, à l'exception de la version mineure JDK utilisée pour la compilation. 

J'ai essayé de rechercher le SerializationConfig.class dans ma version locale et dans la version jenkin,

La sortie de la commande ci-dessous est,

find . -type f -name '*.jar' -print0 |  xargs -0 -I '{}' sh -c 'jar tf {} | grep SerializationConfig.class &&  echo {}'

Guerre locale O/P: -

com/fasterxml/jackson/databind/SerializationConfig.class
./jackson-databind-2.7.3.jar
org/codehaus/jackson/map/SerializationConfig.class
./jackson-mapper-asl-1.9.13.jar
com/fasterxml/jackson/databind/SerializationConfig.class
./jersey-all-2.18.jar

Jenkin war O/P: -

com/fasterxml/jackson/databind/SerializationConfig.class
./jersey-all-2.18.jar
org/codehaus/jackson/map/SerializationConfig.class
./jackson-mapper-asl-1.9.13.jar
com/fasterxml/jackson/databind/SerializationConfig.class
./jackson-databind-2.7.3.jar

En gros, j’injecte ObjectMapper dans ma classe TestRestConfiguration comme suit,

@Inject
    private ObjectMapper objectMapper;

Pas sûr, pourquoi le fichier de guerre généré par Jenkin pose problème.

Toute aide à ce sujet sera appréciée.

9
user1578872

Vous semblez extraire la même classe (SerializationConfig) de deux dépendances différentes du fichier jar. D'après votre question, il est clair que celui de com.fasterxml.jackson.databind (qui est cité dans la trace de pile) se trouve dans le fichier jackson-databind-2.7.3.jar ou dans le fichier jersey-all-2.18.jar. :

com/fasterxml/jackson/databind/SerializationConfig.class
./jackson-databind-2.7.3.jar
org/codehaus/jackson/map/SerializationConfig.class
./jackson-mapper-asl-1.9.13.jar
com/fasterxml/jackson/databind/SerializationConfig.class
./jersey-all-2.18.jar

Je voudrais d’abord essayer de réduire vos dépendances de telle sorte que vous dépendiez de jackson-databind-2.7.3.jar ou de jersey-all-2.18.jar, mais pas des deux. Si votre application fonctionnera avec l'une ou l'autre, je suspecte que cela résoudra votre problème (bien que j'avoue que j'aurais pu m'attendre à voir le message "Aucun type unique de type ... défini" de Spring et je ne l'ai pas remarqué. dans votre post).

Quoi qu'il en soit, si je ne me trompe pas, vous voyez alors un artefact de chargement de classe se déroulant différemment dans votre environnement local par rapport à ce qui se passe dans l'artefact généré par Jenkins et déployé sur votre serveur (complexité supplémentaire ici - vous voudrez peut-être examiner votre serveur pour toutes les bibliothèques fournies et comprendre exactement dans quel ordre se déroule le chargement de votre classe - pas amusant, je sais).

En regardant dans le code source de la classe SerializationConfig de Jackson, je trouve ce qui suit, ce qui pourrait rendre les choses intéressantes si les classes des deux fichiers jar différents ne sont pas identiques.

private static final long serialVersionUID = 1

J'espère que ça aide. Bonne chance!

EDIT 1:

Il peut être intéressant de configurer une paire de versions produisant ce que l’on appelle des fichiers "jar fat" avec un serveur intégré tel que Tomcat ou Jetty. Vous pourriez en tirer des enseignements si vous comparez le comportement de celui que vous produisez localement à celui de Jenkins. Voyez-vous le même problème? En utilisant les gros fichiers jar, vous avez un contrôle plus explicite sur l'environnement déployé que si vous le déployez dans un conteneur existant (et préconfiguré, modifiable).

EDIT 2:

Un couple de choses que vous pourriez faire aider à comprendre vos différences d'environnement.

mvn dependency:tree

ou, si vous avez beaucoup de patience

mvn -X
11
unigeek

Etes-vous sûr que Jenkins nettoie la construction, c’est-à-dire qu’il appelle "mvn clean install" et pas seulement "mvn install"? Une fois que j'ai utilisé "mvn clean install" sur mon local, l'exception a disparu et l'application est lancée avec succès.

    <dependency>
        <groupId>com.fasterxml.jackson.core</groupId>
        <artifactId>jackson-databind</artifactId>
        <version>2.7.4</version>
    </dependency>

    <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-core</artifactId>
            <version>2.7.4</version>
    </dependency>

    <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-annotations</artifactId>
            <version>2.7.4</version>
    </dependency>
3
pingpong