2016-09-09 20 views
8

Mam aplikację do rozruchu wiosennego, która działa dobrze, gdy wykonuję instalację przy użyciu "instalacji czystej mvn" w moim lokalnym, ale kiedy wojna jest generowana przez Jenkin, powoduje to zgłoszenie następującego błędu.Jackson Databind classpath issue

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) 

prostu próbowałem porównując pliki War 2 korzystając z niczym porównać i ja nie widzę żadnych diff wyjątkiem wersji JDK moll używany do kompilacji.

Starałem się wyszukać SerializationConfig.class w mojej lokalnej produkcji oraz w budowie Jenkin,

Wyjście polecenia poniżej jest

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

Lokalna wojna 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 wojna 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 

Zasadniczo wstrzyknąć ObjectMapper w mojej klasie TestRestConfiguration następująco,

@Inject 
    private ObjectMapper objectMapper; 

Nie wiem, dlaczego plik war generowane przez Jenkin jest przyczyną problemu.

Każda pomoc w tym zakresie zostanie doceniona.

Odpowiedz

7

Wygląda na ciągnięcie tej samej klasy (SerializationConfig) z dwóch różnych zależności pliku jar. Z twojego pytania wynika, że ​​ten w com.fasterxml.jackson.databind (który jest cytowany w zapisie stosu) można znaleźć w jackson-databind-2.7.3.jar lub w 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 

chciałbym najpierw spróbować pare powrotem swoje zależności takie, które opierają się na obu Jackson-databind-2.7.3.jar or jersey-all-2.18.jar, ale nie jednocześnie. Jeśli twoja aplikacja będzie działać z jednym lub drugim, podejrzewam, że to rozwiąże twój problem (chociaż przyznaję, że mogłem się spodziewać, że pojawi się komunikat "Brak unikatowej fasoli typu ... jest zdefiniowany" i nie zauważyłem tego w twoim poście).

W każdym razie, jeśli mam rację, to to, co widzisz, jest artefaktem ładującym klasy, który dzieje się inaczej w twoim lokalnym środowisku, w porównaniu z tym, co dzieje się w artefakcie generowanym przez Jenkinsa i umieszczonym na twoim serwerze (dodatkowa złożoność tutaj: -możesz chcieć sprawdzić swój serwer pod kątem dostarczonych bibliotek i dokładnie zrozumieć, w jakiej kolejności odbywa się ładowanie klasowe - nie jest zabawne, wiem).

zerkanie na source code dla klasy SerializationConfig Jacksona, znaleźć następujące dane, które mogłyby dokonać rzeczy interesujące, jeśli zajęcia w dwóch różnych plikach jar nie są właściwie identyczne ..

private static final long serialVersionUID = 1 

nadzieję, że to pomaga. Powodzenia!

EDIT 1:

To może być interesujące, aby skonfigurować parę buduje produkcji tak zwanych plików „tłuszcz Jar” z jakiegoś wbudowanego serwera jak Tomcat lub Jetty. Możesz się czegoś z tego nauczyć, jeśli porównasz zachowanie tego, które produkujesz lokalnie, z tym produkowanym na Jenkins. Czy widzisz ten sam problem?Korzystając z plików słoików tłuszczu, masz bardziej wyraźną kontrolę nad wdrożonym środowiskiem niż w przypadku wdrożenia w istniejącym (i wstępnie skonfigurowanym, możliwym do zmienienia) kontenerze.

EDIT 2:

Kilka rzeczy, które może zrobić help zorientować się swoimi różnicami środowiska ..

mvn dependency:tree 

lub, jeśli masz dużo cierpliwości

mvn -X 
2

Are jesteś pewien, że Jenkins czyści kompilację, tzn. że nazywa "mvn clean install", a nie tylko "mvn install"? Kiedyś użyłem "mvn clean install" na moim lokalnym zniknął wyjątek i aplikacja została pomyślnie uruchomiona.

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