所以我的主项目中有一组子项目。第一个项目(在下面的示例中称为mainCode
)实现了应用程序的完整功能。但是,WidgetAImpl
和WidgetBImpl
被分隔为单独的子项目,以便在需要修复时可以单独部署它们。 WidgetAImpl
和WidgetBImpl
类与接口WidgetInterface
位于同一个包中。
这是项目布局:
project
+ mainCode
+ /src/main/java/com/mycompany/myproject/Application.java
+ /src/main/java/com/mycompany/myproject/AppConfig.java
+ /src/main/java/com/mycompany/myproject/widgets/WidgetInterface.java
+ widgets
+ WidgetA
+ /src/main/java/com/mycompany/myproject/widgets/WidgetAImpl.java
+ WidgetB
+ /src/main/java/com/mycompany/myproject/widgets/WidgetBImpl.java
我已经通过这样的方式构建这些项目,以便mainCode
项目成为我们用于部署到tomcat的war文件,并且每个小部件都会生成一个jar文件。目标是将jar文件添加到tomcat的类路径中,并且war文件单独部署。我花了一天时间让Gradle构建WidgetAImpl
项目,声明mainCode
项目是一个依赖项。所以Gradle现在正确地构建它们,我有mainCode.war
和WidgetAImpl.jar
以及WidgetBImpl.jar
文件。在实现中,小部件都与Autowired HashMap结合在一起,以便在运行时在单个HashMap中创建所有实现的小部件。我通过catalina.properties sharedLoader属性将小部件添加到tomcat的类路径中。
我的问题是,当我将war文件部署到tomcat时,我收到以下错误(为空间修剪):
2017-11-15 21:55:39.841 WARN 16687 --- [nio-8443-exec-4] ationConfigEmbeddedWebApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'org.springframework.scheduling.annotation.ProxyAsyncConfiguration': Unsatisfied dependency expressed through method 'setConfigurers' parameter 0; nested exception is org.springframework.beans.factory.CannotLoadBeanClassException: Error loading class [com.mycompany.myproject.widgets.WidgetAImpl] for bean with name 'WidgetAImpl' defined in URL [jar:file:/mycompany/libs/WidgetAImpl.jar!/com/mycompany/myproject/widgets/WidgetAImpl.class]: problem with class file or dependent class; nested exception is java.lang.NoClassDefFoundError: com/mycompany/myproject/widgets/WidgetInterface
2017-11-15 21:55:39.845 ERROR 16687 --- [nio-8443-exec-4] o.s.b.f.s.DefaultListableBeanFactory : Destroy method on bean with name 'org.springframework.boot.context.properties.ConfigurationPropertiesBindingPostProcessor' threw an exception
java.lang.IllegalStateException: ApplicationEventMulticaster not initialized - call 'refresh' before multicasting events via the context: org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext@3633386f: startup date [Wed Nov 15 21:55:38 UTC 2017]; root of context hierarchy
at org.springframework.context.support.AbstractApplicationContext.getApplicationEventMulticaster(AbstractApplicationContext.java:404) [spring-context-4.3.4.RELEASE.jar:4.3.4.RELEASE]
at org.springframework.context.support.ApplicationListenerDetector.postProcessBeforeDestruction(ApplicationListenerDetector.java:97) ~[spring-context-4.3.4.RELEASE.jar:4.3.4.RELEASE]
at org.springframework.beans.factory.support.DisposableBeanAdapter.destroy(DisposableBeanAdapter.java:253) ~[spring-beans-4.3.4.RELEASE.jar:4.3.4.RELEASE]
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.destroyBean(DefaultSingletonBeanRegistry.java:578) [spring-beans-4.3.4.RELEASE.jar:4.3.4.RELEASE]
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.destroySingleton(DefaultSingletonBeanRegistry.java:554) [spring-beans-4.3.4.RELEASE.jar:4.3.4.RELEASE]
at org.springframework.beans.factory.support.DefaultListableBeanFactory.destroySingleton(DefaultListableBeanFactory.java:954) [spring-beans-4.3.4.RELEASE.jar:4.3.4.RELEASE]
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.destroySingletons(DefaultSingletonBeanRegistry.java:523) [spring-beans-4.3.4.RELEASE.jar:4.3.4.RELEASE]
at org.springframework.beans.factory.support.DefaultListableBeanFactory.destroySingletons(DefaultListableBeanFactory.java:961) [spring-beans-4.3.4.RELEASE.jar:4.3.4.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.destroyBeans(AbstractApplicationContext.java:1033) [spring-context-4.3.4.RELEASE.jar:4.3.4.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:555) [spring-context-4.3.4.RELEASE.jar:4.3.4.RELEASE]
at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh(EmbeddedWebApplicationContext.java:122) [spring-boot-1.4.2.RELEASE.jar:1.4.2.RELEASE]
...
Caused by: org.springframework.beans.factory.CannotLoadBeanClassException: Error loading class [com.mycompany.myproject.widgets.WidgetAImpl] for bean with name 'WidgetAImpl' defined in URL [jar:file:/mycompany/libs/WidgetAImpl.jar!/com/mycompany/myproject/widgets/WidgetAImpl.class]: problem with class file or dependent class; nested exception is java.lang.NoClassDefFoundError: com/mycompany/myproject/widgets/WidgetInterface
at org.springframework.beans.factory.support.AbstractBeanFactory.resolveBeanClass(AbstractBeanFactory.java:1364) ~[spring-beans-4.3.4.RELEASE.jar:4.3.4.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.determineTargetType(AbstractAutowireCapableBeanFactory.java:639) ~[spring-beans-4.3.4.RELEASE.jar:4.3.4.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.predictBeanType(AbstractAutowireCapableBeanFactory.java:607) ~[spring-beans-4.3.4.RELEASE.jar:4.3.4.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.isFactoryBean(AbstractBeanFactory.java:1456) ~[spring-beans-4.3.4.RELEASE.jar:4.3.4.RELEASE]
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doGetBeanNamesForType(DefaultListableBeanFactory.java:420) ~[spring-beans-4.3.4.RELEASE.jar:4.3.4.RELEASE]
at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBeanNamesForType(DefaultListableBeanFactory.java:390) ~[spring-beans-4.3.4.RELEASE.jar:4.3.4.RELEASE]
at org.springframework.beans.factory.BeanFactoryUtils.beanNamesForTypeIncludingAncestors(BeanFactoryUtils.java:220) ~[spring-beans-4.3.4.RELEASE.jar:4.3.4.RELEASE]
at org.springframework.beans.factory.support.DefaultListableBeanFactory.findAutowireCandidates(DefaultListableBeanFactory.java:1243) ~[spring-beans-4.3.4.RELEASE.jar:4.3.4.RELEASE]
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveMultipleBeans(DefaultListableBeanFactory.java:1164) ~[spring-beans-4.3.4.RELEASE.jar:4.3.4.RELEASE]
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1089) ~[spring-beans-4.3.4.RELEASE.jar:4.3.4.RELEASE]
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1059) ~[spring-beans-4.3.4.RELEASE.jar:4.3.4.RELEASE]
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredMethodElement.inject(AutowiredAnnotationBeanPostProcessor.java:663) ~[spring-beans-4.3.4.RELEASE.jar:4.3.4.RELEASE]
... 68 common frames omitted
Caused by: java.lang.NoClassDefFoundError: com/mycompany/myproject/widgets/WidgetInterface
at java.lang.ClassLoader.defineClass1(Native Method) ~[na:1.8.0_144]
at java.lang.ClassLoader.defineClass(Unknown Source) ~[na:1.8.0_144]
at java.security.SecureClassLoader.defineClass(Unknown Source) ~[na:1.8.0_144]
at java.net.URLClassLoader.defineClass(Unknown Source) ~[na:1.8.0_144]
at java.net.URLClassLoader.access$100(Unknown Source) ~[na:1.8.0_144]
at java.net.URLClassLoader$1.run(Unknown Source) ~[na:1.8.0_144]
at java.net.URLClassLoader$1.run(Unknown Source) ~[na:1.8.0_144]
at java.security.AccessController.doPrivileged(Native Method) ~[na:1.8.0_144]
at java.net.URLClassLoader.findClass(Unknown Source) ~[na:1.8.0_144]
at java.lang.ClassLoader.loadClass(Unknown Source) ~[na:1.8.0_144]
at java.lang.ClassLoader.loadClass(Unknown Source) ~[na:1.8.0_144]
at java.lang.Class.forName0(Native Method) ~[na:1.8.0_144]
at java.lang.Class.forName(Unknown Source) ~[na:1.8.0_144]
at org.apache.catalina.loader.WebappClassLoaderBase.loadClass(WebappClassLoaderBase.java:1271) ~[catalina.jar:8.5.20]
at org.apache.catalina.loader.WebappClassLoaderBase.loadClass(WebappClassLoaderBase.java:1119) ~[catalina.jar:8.5.20]
at org.springframework.util.ClassUtils.forName(ClassUtils.java:250) ~[spring-core-4.3.4.RELEASE.jar:4.3.4.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanDefinition.resolveBeanClass(AbstractBeanDefinition.java:394) ~[spring-beans-4.3.4.RELEASE.jar:4.3.4.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.doResolveBeanClass(AbstractBeanFactory.java:1408) ~[spring-beans-4.3.4.RELEASE.jar:4.3.4.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.resolveBeanClass(AbstractBeanFactory.java:1353) ~[spring-beans-4.3.4.RELEASE.jar:4.3.4.RELEASE]
... 79 common frames omitted
Caused by: java.lang.ClassNotFoundException: com.mycompany.myproject.widgets.WidgetInterface
at java.net.URLClassLoader.findClass(Unknown Source) ~[na:1.8.0_144]
at java.lang.ClassLoader.loadClass(Unknown Source) ~[na:1.8.0_144]
at java.lang.ClassLoader.loadClass(Unknown Source) ~[na:1.8.0_144]
... 98 common frames omitted
(完全异常堆栈跟踪:https://pastebin.com/KwaNGaeN)
从中可以看出Spring无法找到我的WidgetInterface。但是,我已经确认war文件中的WidgetInterface类文件是。此外,它与WidgetAImpl和WidgetBImpl是相同的java包(即使它们在单独的文件中)。为什么它不能看到WidgetInterface?
答案 0 :(得分:1)
您可以使用parseDouble
创建common
或base
模块吗?将其作为小部件添加到Tomcat。然后所有其他的罐子和战争可以依靠那个共同的部分。 Tomcat将有如何加载它的干净路径,其他模块使用的是什么。