我有一个弹簧启动应用程序,当我使用" mvn clean install"进行部署时工作正常。在我的本地,但是当通过Jenkin产生战争时,它会抛出以下错误。
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)
我只是尝试使用超比较来比较2个war文件,除了用于编译的JDK次要版本之外我没有看到任何差异。
我尝试在本地构建和jenkin构建中搜索SerializationConfig.class,
以下命令的输出是,
find . -type f -name '*.jar' -print0 | xargs -0 -I '{}' sh -c 'jar tf {} | grep SerializationConfig.class && echo {}'
地方战争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
基本上,我在我的TestRestConfiguration类中注入ObjectMapper,如下所示,
@Inject
private ObjectMapper objectMapper;
不确定,为什么通过Jenkin生成的war文件会导致问题。
对此有任何帮助将不胜感激。
答案 0 :(得分:11)
您似乎从两个不同的jar文件依赖项中提取相同的类(SerializationConfig)。从您的问题来看,很明显com.fasterxml.jackson.databind(在堆栈跟踪中引用)中的那个可以在jackson-databind-2.7.3.jar或者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
我首先会尝试削减您的依赖关系,以便您依赖jackson-databind-2.7.3.jar或者jersey-all-2.18.jar,但不能同时依赖两者。如果您的应用程序可以与其中一个一起使用,我怀疑这将解决您的问题(尽管我承认我可能希望看到Spring的“没有定义类型的唯一bean ...”消息并且我没有注意到它在你的帖子中。)
无论如何,如果我是正确的,那么你所看到的是在本地环境中以不同方式发生的类加载工件与在Jenkins生成的工件中发生并在服务器上部署的内容(这里的额外复杂性 - 您可能想要仔细检查您的服务器是否有任何提供的库,并确切了解您的类加载的顺序 - 我知道这并不好玩。
在Jackson的SerializationConfig类的source code上偷看,我发现以下内容,如果两个不同jar文件中的类实际上不相同,这可能会让事情变得有趣。
private static final long serialVersionUID = 1
希望它有所帮助。祝你好运!
编辑1:
建立一对带有一些嵌入式服务器(如Tomcat或Jetty)的所谓“胖罐”文件的构建可能会很有趣。如果您比较本地生成的行为与Jenkins生成的行为,您可能会从中学到一些东西。你看到同样的问题吗?使用胖jar文件,您可以比部署到现有(和预配置,可更改的)容器中更明确地控制部署环境。
编辑2:
您可能要做的一些事情有助于找出您的环境差异。
mvn dependency:tree
或者,如果你有很多耐心
mvn -X
答案 1 :(得分:3)
你确定Jenkins清理了构建,即它称为“mvn clean install”而不仅仅是“mvn install”吗?一旦我在我的本地使用“mvn clean install”,异常就消失了,应用程序也成功启动了。
<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>