Maven EAR 依赖结构
Maven EAR dependency structure
我正在尝试使用最新的 JBoss 工具通过 Eclipse Neon 将 EAR 部署到 Wildfly 10。这是我第一次尝试使用 EAR,所以我记录了自己,这是我想出的结构:
Maven 模块:
api
(类型 jar
,无依赖项):包含接口 MyService
和 Person
。
ejb
(类型 ejb
,取决于 api
):包含 MyService
的 @Stateless
实现和 @Entity
的实现Person
.
war
(类型 war
,取决于 api
):包含使用 MyService
. 的 JAX-RS 资源
ear
(类型 ear
,取决于 ejb
和 war
):EAR 模块。
(完整来源见此处:https://github.com/heruan/maven-ear-example)
问题是当我将它部署到 Wildfly 时,我得到:
java.lang.NoClassDefFoundError: Failed to link ejb/MyServiceImpl: api/MyService
完整堆栈跟踪:
INFO [org.jboss.weld.deployer] (MSC service thread 1-6) WFLYWELD0003: Processing weld deployment ear-1.0.0.ear
WARN [org.jboss.modules] (MSC service thread 1-6) Failed to define class ejb.MyServiceImpl in Module "deployment.ear-1.0.0.ear.ejb-1.0.0.jar:main" from Service Module Loader: java.lang.NoClassDefFoundError: Failed to link ejb/MyServiceImpl (Module "deployment.ear-1.0.0.ear.ejb-1.0.0.jar:main" from Service Module Loader): api/MyService
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
at sun.reflect.DelegatingConstructorAccessorImpl.__newInstance(DelegatingConstructorAccessorImpl.java:45)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java)
at java.lang.reflect.Constructor.newInstance(Constructor.java:422)
at org.jboss.modules.ModuleClassLoader.defineClass(ModuleClassLoader.java:446)
at org.jboss.modules.ModuleClassLoader.loadClassLocal(ModuleClassLoader.java:274)
at org.jboss.modules.ModuleClassLoader.loadClassLocal(ModuleClassLoader.java:78)
at org.jboss.modules.Module.loadModuleClass(Module.java:606)
at org.jboss.modules.ModuleClassLoader.findClass(ModuleClassLoader.java:190)
at org.jboss.modules.ConcurrentClassLoader.performLoadClassUnchecked(ConcurrentClassLoader.java:363)
at org.jboss.modules.ConcurrentClassLoader.performLoadClass(ConcurrentClassLoader.java:351)
at org.jboss.modules.ConcurrentClassLoader.loadClass(ConcurrentClassLoader.java:93)
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:348)
at org.jboss.as.ee.utils.ClassLoadingUtils.loadClass(ClassLoadingUtils.java:21)
at org.jboss.as.ee.utils.ClassLoadingUtils.loadClass(ClassLoadingUtils.java:14)
at org.jboss.as.ee.component.deployers.InterceptorAnnotationProcessor.processComponentConfig(InterceptorAnnotationProcessor.java:84)
at org.jboss.as.ee.component.deployers.InterceptorAnnotationProcessor.deploy(InterceptorAnnotationProcessor.java:76)
at org.jboss.as.server.deployment.DeploymentUnitPhaseService.start(DeploymentUnitPhaseService.java:147)
at org.jboss.msc.service.ServiceControllerImpl$StartTask.startService(ServiceControllerImpl.java:1948)
at org.jboss.msc.service.ServiceControllerImpl$StartTask.run(ServiceControllerImpl.java:1881)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)
我错过了什么?我的目标是让最基本的 EAR 具有由其模块共享的通用 JPA 持久性单元。
我发现了问题所在:.class
文件重复。似乎 Maven EAR 插件不够聪明,无法避免重复依赖,因此您需要将它们显式设置为 provided
.
例如示例项目中的解决方案是在war
的pom.xml
中将api
模块设置为provided
:
<dependency>
<groupId>com.example</groupId>
<artifactId>api</artifactId>
<version>1.0.0</version>
<scope>provided</scope>
</dependency>
我正在尝试使用最新的 JBoss 工具通过 Eclipse Neon 将 EAR 部署到 Wildfly 10。这是我第一次尝试使用 EAR,所以我记录了自己,这是我想出的结构:
Maven 模块:
api
(类型jar
,无依赖项):包含接口MyService
和Person
。ejb
(类型ejb
,取决于api
):包含MyService
的@Stateless
实现和@Entity
的实现Person
.war
(类型war
,取决于api
):包含使用MyService
. 的 JAX-RS 资源
ear
(类型ear
,取决于ejb
和war
):EAR 模块。
(完整来源见此处:https://github.com/heruan/maven-ear-example)
问题是当我将它部署到 Wildfly 时,我得到:
java.lang.NoClassDefFoundError: Failed to link ejb/MyServiceImpl: api/MyService
完整堆栈跟踪:
INFO [org.jboss.weld.deployer] (MSC service thread 1-6) WFLYWELD0003: Processing weld deployment ear-1.0.0.ear
WARN [org.jboss.modules] (MSC service thread 1-6) Failed to define class ejb.MyServiceImpl in Module "deployment.ear-1.0.0.ear.ejb-1.0.0.jar:main" from Service Module Loader: java.lang.NoClassDefFoundError: Failed to link ejb/MyServiceImpl (Module "deployment.ear-1.0.0.ear.ejb-1.0.0.jar:main" from Service Module Loader): api/MyService
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
at sun.reflect.DelegatingConstructorAccessorImpl.__newInstance(DelegatingConstructorAccessorImpl.java:45)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java)
at java.lang.reflect.Constructor.newInstance(Constructor.java:422)
at org.jboss.modules.ModuleClassLoader.defineClass(ModuleClassLoader.java:446)
at org.jboss.modules.ModuleClassLoader.loadClassLocal(ModuleClassLoader.java:274)
at org.jboss.modules.ModuleClassLoader.loadClassLocal(ModuleClassLoader.java:78)
at org.jboss.modules.Module.loadModuleClass(Module.java:606)
at org.jboss.modules.ModuleClassLoader.findClass(ModuleClassLoader.java:190)
at org.jboss.modules.ConcurrentClassLoader.performLoadClassUnchecked(ConcurrentClassLoader.java:363)
at org.jboss.modules.ConcurrentClassLoader.performLoadClass(ConcurrentClassLoader.java:351)
at org.jboss.modules.ConcurrentClassLoader.loadClass(ConcurrentClassLoader.java:93)
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:348)
at org.jboss.as.ee.utils.ClassLoadingUtils.loadClass(ClassLoadingUtils.java:21)
at org.jboss.as.ee.utils.ClassLoadingUtils.loadClass(ClassLoadingUtils.java:14)
at org.jboss.as.ee.component.deployers.InterceptorAnnotationProcessor.processComponentConfig(InterceptorAnnotationProcessor.java:84)
at org.jboss.as.ee.component.deployers.InterceptorAnnotationProcessor.deploy(InterceptorAnnotationProcessor.java:76)
at org.jboss.as.server.deployment.DeploymentUnitPhaseService.start(DeploymentUnitPhaseService.java:147)
at org.jboss.msc.service.ServiceControllerImpl$StartTask.startService(ServiceControllerImpl.java:1948)
at org.jboss.msc.service.ServiceControllerImpl$StartTask.run(ServiceControllerImpl.java:1881)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)
我错过了什么?我的目标是让最基本的 EAR 具有由其模块共享的通用 JPA 持久性单元。
我发现了问题所在:.class
文件重复。似乎 Maven EAR 插件不够聪明,无法避免重复依赖,因此您需要将它们显式设置为 provided
.
例如示例项目中的解决方案是在war
的pom.xml
中将api
模块设置为provided
:
<dependency>
<groupId>com.example</groupId>
<artifactId>api</artifactId>
<version>1.0.0</version>
<scope>provided</scope>
</dependency>