Jackson Databind类路径问题 [英] Jackson Databind classpath issue

查看:119
本文介绍了Jackson Databind类路径问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个Spring Boot应用程序,当我在本地使用"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

詹金战争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

基本上,我将ObjectMapper注入到我的TestRestConfiguration类中,如下所示,

@Inject
    private ObjectMapper objectMapper;

不确定,为什么通过詹金(Jenkin)生成的war文件引起了问题.

在此方面的任何帮助将不胜感激.

解决方案

您似乎正在从两个不同的jar文件依赖项中提取同一类(SerializationConfig).从您的问题来看,很明显,可以在jackson-databind-2.7.3.jar或jersey-all-2.18.jar中找到com.fasterxml.jackson.databind(在堆栈跟踪中引用)中的一个. :

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生成的工件中以及部署在您的服务器上所发生的事情有所不同(这里的附加复杂性-您可能要仔细检查服务器中是否提供了任何库,并确切了解类加载的顺序-我知道这很有趣.

源代码,如果两个不同的jar文件中的类实际上并不相同,这可能会使事情变得有趣.

private static final long serialVersionUID = 1

希望它会有所帮助.祝你好运!

设置一些构建程序可能会很有趣,这些构建程序使用某些嵌入式服务器(例如Tomcat或Jetty)来生成所谓的胖罐"文件.如果您将本地生产的产品与詹金斯生产的产品的行为进行比较,您可能会从中学到一些东西.你看到同样的问题吗?使用胖子jar文件,与将其部署到现有(且预先配置的,可变的)容器中相比,您对部署的环境具有更明确的控制.

您可能需要做的事情有助于找出环境差异.

mvn dependency:tree

或者,如果您有足够的耐心

mvn -X

I have a spring boot app which works fine when i do the deploy using "mvn clean install" in my local, but when the war is generated through Jenkin, it is throwing the following error.

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)

I just tried comparing the 2 war files using beyond compare and i dont see any diff except the JDK minor version being used to compile.

I tried to search for the SerializationConfig.class in my local build and in the jenkin build,

The output for the below command is,

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

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

Basically, I inject the ObjectMapper in my TestRestConfiguration class as follows,

@Inject
    private ObjectMapper objectMapper;

Not sure, why the war file being generated through Jenkin is causing problem.

Any help on this will be appreciated.

解决方案

You appear to be pulling the same class (SerializationConfig) from two different jar file dependencies. From your question, it's clear that the one in com.fasterxml.jackson.databind (which is cited in the stack trace) can be found in either the jackson-databind-2.7.3.jar or the 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

I would first try to pare back your dependencies such that you rely on either jackson-databind-2.7.3.jar or jersey-all-2.18.jar, but not both. If your application will work with one or the other, I suspect that this will fix your issue (although I admit that I might have expected to see Spring's "No unique bean of type ... is defined" message and I did not notice it in your post).

Anyway, if I'm correct, then what you're seeing is an artifact of class loading happening differently in your local environment vs. what happens in the Jenkins-generated artifact and deployed on your server (additional complexity here--you may want to scrutinize your server for any provided libs and understand exactly what order your class loading is happening--not fun, I know).

Peeking at the source code for Jackson's SerializationConfig class, I find the following, which could make things interesting if the classes in the two different jar files are not actually identical..

private static final long serialVersionUID = 1

Hope it helps. Good luck!

EDIT 1:

It might be interesting to set up a pair of builds producing so-called "fat jar" files with some embedded server like Tomcat or Jetty. You might learn something from that if you compare behavior of the one you produce locally vs. the one produced on Jenkins. Do you see the same problem? Using the fat jar files, you have more explicit control over the deployed environment than you do if you deploy into an existing (and pre-configured, alterable) container.

EDIT 2:

Couple of things you might to do help figure out your environment differences..

mvn dependency:tree

or, if you have a lot of patience

mvn -X

这篇关于Jackson Databind类路径问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆