小编典典

Jackson Databind类路径问题

jenkins

我有一个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文件会引起问题。

任何帮助,将不胜感激。


阅读 618

收藏
2020-07-25

共1个答案

小编典典

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

偷看Jackson的SerializationConfig类的源代码,我发现以下内容,如果两个不同的jar文件中的类实际上并不相同,则可能会使事情变得有趣。

private static final long serialVersionUID = 1

希望能帮助到你。祝好运!

编辑1:

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

编辑2:

您可能需要做的几件事有助于弄清您的环境差异。

mvn dependency:tree

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

mvn -X
2020-07-25