Java Jackson Databind 类路径问题
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/39419160/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Hymanson Databind classpath issue
提问by user1578872
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.
我有一个 Spring Boot 应用程序,当我在本地使用“mvn clean install”进行部署时,它可以正常工作,但是当通过 Jenkins 生成战争时,它会抛出以下错误。
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.Hymanson.databind.ObjectMapper]: Factory method 'objectMapper' threw exception; nested exception is java.lang.NoClassDefFoundError: Could not initialize class com.fasterxml.Hymanson.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.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.Hymanson.databind.ObjectMapper]: Factory method 'objectMapper' threw exception; nested exception is java.lang.NoClassDefFoundError: Could not initialize class com.fasterxml.Hymanson.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.Hymanson.databind.SerializationConfig
at com.fasterxml.Hymanson.databind.ObjectMapper.<init>(ObjectMapper.java:535)
at com.fasterxml.Hymanson.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.
我只是尝试使用 Beyond compare 比较 2 个 war 文件,除了用于编译的 JDK 次要版本之外,我没有看到任何差异。
I tried to search for the SerializationConfig.class in my local build and in the jenkin build,
我试图在我的本地构建和 jenkin 构建中搜索 SerializationConfig.class,
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 :-
局部战争 O/P :-
com/fasterxml/Hymanson/databind/SerializationConfig.class
./Hymanson-databind-2.7.3.jar
org/codehaus/Hymanson/map/SerializationConfig.class
./Hymanson-mapper-asl-1.9.13.jar
com/fasterxml/Hymanson/databind/SerializationConfig.class
./jersey-all-2.18.jar
Jenkin war O/P :-
詹金战争 O/P :-
com/fasterxml/Hymanson/databind/SerializationConfig.class
./jersey-all-2.18.jar
org/codehaus/Hymanson/map/SerializationConfig.class
./Hymanson-mapper-asl-1.9.13.jar
com/fasterxml/Hymanson/databind/SerializationConfig.class
./Hymanson-databind-2.7.3.jar
Basically, I inject the ObjectMapper in my TestRestConfiguration class as follows,
基本上,我在 TestRestConfiguration 类中注入 ObjectMapper,如下所示,
@Inject
private ObjectMapper objectMapper;
Not sure, why the war file being generated through Jenkin is causing problem.
不确定,为什么通过 Jenkins 生成的 war 文件会导致问题。
Any help on this will be appreciated.
对此的任何帮助将不胜感激。
采纳答案by unigeek
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.Hymanson.databind (which is cited in the stack trace) can be found in either the Hymanson-databind-2.7.3.jar or the jersey-all-2.18.jar:
您似乎从两个不同的 jar 文件依赖项中提取相同的类 (SerializationConfig)。从您的问题来看,很明显 com.fasterxml.Hymanson.databind (在堆栈跟踪中引用)中的那个可以在 Hymanson-databind-2.7.3.jar 或 jersey-all-2.18.jar 中找到:
com/fasterxml/Hymanson/databind/SerializationConfig.class
./Hymanson-databind-2.7.3.jar
org/codehaus/Hymanson/map/SerializationConfig.class
./Hymanson-mapper-asl-1.9.13.jar
com/fasterxml/Hymanson/databind/SerializationConfig.class
./jersey-all-2.18.jar
I would first try to pare back your dependencies such that you rely on either Hymanson-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).
我会首先尝试减少您的依赖项,以便您依赖 Hymanson-databind-2.7.3.jar 或 jersey-all-2.18.jar,但不能同时依赖两者。如果您的应用程序将与其中一个一起工作,我怀疑这将解决您的问题(尽管我承认我可能希望看到 Spring 的“没有唯一类型的 bean ... 被定义”消息,但我没有注意到它在您的帖子中)。
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).
无论如何,如果我是对的,那么您所看到的是在本地环境中发生的类加载工件与在 Jenkins 生成的工件中发生并部署在您的服务器上的情况不同(这里有额外的复杂性 - 您可能想要检查您的服务器是否提供任何提供的库,并准确了解您的类加载发生的顺序 - 不好玩,我知道)。
Peeking at the source codefor Hymanson'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..
查看Hymanson 的 SerializationConfig 类的源代码,我发现以下内容,如果两个不同 jar 文件中的类实际上并不相同,这可能会使事情变得有趣。
private static final long serialVersionUID = 1
Hope it helps. Good luck!
希望能帮助到你。祝你好运!
EDIT 1:
编辑 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.
使用某些嵌入式服务器(如 Tomcat 或 Jetty)设置一对构建生成所谓的“fat jar”文件可能会很有趣。如果您比较本地生产的产品与 Jenkins 生产的产品的行为,您可能会从中学到一些东西。你看到同样的问题了吗?使用胖 jar 文件,与部署到现有(和预先配置的、可更改的)容器相比,您可以更明确地控制部署的环境。
EDIT 2:
编辑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
回答by pingpong
Are you sure that Jenkins cleans the build, i.e. that it calls "mvn cleaninstall" and not only "mvn install" ? Once I used "mvn clean install" on my local the exception disappeared and the app is successfully launched.
您确定 Jenkins 会清理构建,即它调用“mvn cleaninstall”而不仅仅是“mvn install”?一旦我在本地使用“mvn clean install”,异常就会消失并且应用程序成功启动。
<dependency>
<groupId>com.fasterxml.Hymanson.core</groupId>
<artifactId>Hymanson-databind</artifactId>
<version>2.7.4</version>
</dependency>
<dependency>
<groupId>com.fasterxml.Hymanson.core</groupId>
<artifactId>Hymanson-core</artifactId>
<version>2.7.4</version>
</dependency>
<dependency>
<groupId>com.fasterxml.Hymanson.core</groupId>
<artifactId>Hymanson-annotations</artifactId>
<version>2.7.4</version>
</dependency>