Spring引导devtools加载两次类并导致LinkageError



IDE是Idea,Spring启动项目有META-INF/spring-devtools.properties,内容是

restart.include.dozer=/dozer-5.5.1.jar

当运行项目时抛出异常

2015-12-03 12:02:49,491 [restartedMain] INFO  org.dozer.DozerBeanMapper - Initializing a new instance of dozer bean mapper.
2015-12-03 12:02:49,494 [restartedMain] WARN  o.s.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext - Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'dozerBeanMapper' defined in class path resource [com/foo/common/CommonConfiguration.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.dozer.Mapper]: Factory method 'dozerBeanMapper' threw exception; nested exception is java.lang.LinkageError: loader constraint violation: loader (instance of org/springframework/boot/devtools/restart/classloader/RestartClassLoader) previously initiated loading for a different type with name "org/dozer/DozerBeanMapper"
2015-12-03 12:02:49,517 [restartedMain] ERROR org.springframework.boot.SpringApplication - Application startup failed
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'dozerBeanMapper' defined in class path resource [com/foo/common/CommonConfiguration.class]: Bean instantiation via factory method failed; nested exception is    org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.dozer.Mapper]: Factory method 'dozerBeanMapper' threw exception; nested exception is java.lang.LinkageError: loader constraint violation: loader (instance of org/springframework/boot/devtools/restart/classloader/RestartClassLoader) previously initiated loading for a different type with name "org/dozer/DozerBeanMapper"
at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:599) ~[spring-beans-4.2.3.RELEASE.jar:4.2.3.RELEASE]

奇怪的是,当在Eclipse中运行项目时,没有上述问题。在想法中添加-XX:+TraceClassLoading配置,我发现推土机装载了两次。

9569 [Loaded org.dozer.DozerBeanMapper from file:/C:/Users/otto/.m2/repository/net/sf/dozer/dozer/5.5.1/dozer-5.5.1.jar]
9618 [Loaded org.dozer.DozerBeanMapper from file:/C:/Users/otto/.m2/repository/net/sf/dozer/dozer/5.5.1/dozer-5.5.1.jar]

现在我不知道如何找到这个问题的原因?

您共享的项目自述文件中有一些关键信息不包括在问题中:

下载示例项目,然后将此项目导入eclipse,关闭条形项目,然后运行FooApplication,您可能会得到以下错误

关闭酒吧项目意味着其课程将无法重新启动。这意味着它们将由主类加载器而不是重新启动类加载器加载。栏中的代码取决于Dozer,但您已经配置了DevTools,以便Dozer的类将由重启类加载器加载:

restart.include.dozer=/dozer-5.5.1.jar

我不清楚你为什么要这样配置。如果我删除spring-devtools.properties,你的样品对我来说很好。也许示例没有说明导致您应用该配置的问题?

如果您确实需要这种配置,并且不想在Eclipse中打开bar项目,那么您还需要将bar配置为包含在重新启动中,以便它和它所依赖的Dozer都由重新启动类加载器加载:

restart.include.dozer=/dozer-5.5.1.jar
restart.include.bar=/bar-1.0-SNAPSHOT.jar

最新更新