Java CDI:来自jar的接口无法解析为本地Wildfly 8.0

Java CDI:来自jar的接口无法解析为本地Wildfly 8.0,java,cdi,wildfly,Java,Cdi,Wildfly,我正在尝试将现有的Java 7应用程序从Jboss 7.1迁移到Wildfly 8.0,并且在CDI方面遇到了一些问题 项目结构如下: ear | |--> base.service.impl.war |--> mad.impl.war --> contains SessionServiceImpl.class |--> lib | |-> base.api.jar |-> ba

我正在尝试将现有的Java 7应用程序从Jboss 7.1迁移到Wildfly 8.0,并且在CDI方面遇到了一些问题

项目结构如下:

 ear
    |
    |--> base.service.impl.war
    |--> mad.impl.war --> contains SessionServiceImpl.class
    |--> lib
        |
        |-> base.api.jar
        |-> base.api.impl.jar --> contains SessionService.class
<plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-ear-plugin</artifactId>
            <version>2.8</version>
            <configuration>
                <version>6</version>
                <initializeInOrder>true</initializeInOrder>
                <defaultLibBundleDir>/lib</defaultLibBundleDir>
                <modules>
                    <jarModule>
                            <groupId>mygroup</groupId>
                            <artifactId>com.base.impl</artifactId>
                        </jarModule>

                        <webModule>
                            <groupId>mygroup</groupId>
                            <artifactId>com.base.service.impl</artifactId>
                            <contextRoot>/impl.base.server</contextRoot>
                            <bundleFileName>com.base.impl.war</bundleFileName>
                        </webModule>

                        <webModule>
                            <groupId>mygroup</groupId>
                            <artifactId>com.mad.impl</artifactId>
                            <contextRoot>/impl.mad.server</contextRoot>
                            <bundleFileName>com.mad.impl.war</bundleFileName>
                        </webModule>
                    </modules>
                </configuration>
            </plugin>
SessionService是没有注释的纯Java接口。 SessionServiceImpl如下所示:

@Stateless
@EJB(name = SessionService.JNDI_NAME, beanInterface = SessionService.class)
public class SessionServiceImpl implements SessionService {

}
EJB似乎已注册:

INFO  [org.jboss.as.ejb3.deployment.processors.EjbJndiBindingsDeploymentUnitProcessor] (MSC service thread 1-1) JNDI bindings for session bean named SessionServiceImpl in deployment unit subdeployment "com.mad.impl.war" of deployment "com.deployment.ear.ear" are as follows:

    java:global/com.server.deployment.ear/com.mad.impl/SessionServiceImpl!com.base.session.SessionService
    java:app/com.mad.impl/SessionServiceImpl!com.base.session.SessionService
    java:module/SessionServiceImpl!com.base.session.SessionService
    java:global/com.deployment.ear/com.mad.impl/SessionServiceImpl
    java:app/com.mad.impl/SessionServiceImpl
    java:module/SessionServiceImpl
但在此之后,当CDI容器开始部署时,我会遇到以下错误:

ERROR [org.jboss.msc.service.fail] (MSC service thread 1-2) MSC000001: Failed to start service jboss.deployment.unit."com.deployment.ear.ear".WeldStartService: org.jboss.msc.service.StartException in service jboss.deployment.unit."com.deployment.ear.ear".WeldStartService: Failed to start service
    at org.jboss.msc.service.ServiceControllerImpl$StartTask.run(ServiceControllerImpl.java:1904) [jboss-msc-1.2.0.Final.jar:1.2.0.Final]
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145) [rt.jar:1.7.0_45]
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615) [rt.jar:1.7.0_45]
    at java.lang.Thread.run(Thread.java:744) [rt.jar:1.7.0_45]
Caused by: org.jboss.msc.service.ServiceNotFoundException: Service service jboss.deployment.subunit."com.deployment.ear.ear"."com.mad.impl.war".component.SessionServiceImpl.VIEW."com.base.session.SessionService".LOCAL not found
我试着用@Local注释接口,但没用

Maven ear插件配置如下:

 ear
    |
    |--> base.service.impl.war
    |--> mad.impl.war --> contains SessionServiceImpl.class
    |--> lib
        |
        |-> base.api.jar
        |-> base.api.impl.jar --> contains SessionService.class
<plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-ear-plugin</artifactId>
            <version>2.8</version>
            <configuration>
                <version>6</version>
                <initializeInOrder>true</initializeInOrder>
                <defaultLibBundleDir>/lib</defaultLibBundleDir>
                <modules>
                    <jarModule>
                            <groupId>mygroup</groupId>
                            <artifactId>com.base.impl</artifactId>
                        </jarModule>

                        <webModule>
                            <groupId>mygroup</groupId>
                            <artifactId>com.base.service.impl</artifactId>
                            <contextRoot>/impl.base.server</contextRoot>
                            <bundleFileName>com.base.impl.war</bundleFileName>
                        </webModule>

                        <webModule>
                            <groupId>mygroup</groupId>
                            <artifactId>com.mad.impl</artifactId>
                            <contextRoot>/impl.mad.server</contextRoot>
                            <bundleFileName>com.mad.impl.war</bundleFileName>
                        </webModule>
                    </modules>
                </configuration>
            </plugin>

org.apache.maven.plugins
maven耳朵插件
2.8
6.
真的
/解放党
mygroup
com.base.impl
mygroup
com.base.service.impl
/impl.base.server
com.base.impl.war
mygroup
com.mad.impl
/impl.mad.server
com.mad.impl.war

问题在于无状态bean。CDI在为会话bean注入远程接口方面存在问题。正如错误所示,它正试图为SessionServiceImpl注入本地接口,但这不会发生,因为ejb容器(基于ejb规范)只公开了一个远程接口,因为SessionServiceImpl实现了SessionService,并且没有使用@LocalBean注释

关于ejb3.1的注释:

  • 如果会话bean实现除Serializable之外的任何接口, 可比较、可外部化,则实现的接口将 被认为是bean的远程接口
  • 此外,您还使用@EJB注释定义了远程 SessionServiceImpl的接口,因此它不位于 本地命名空间,但在远程命名空间中

    • 问题在于无状态bean。CDI在为会话bean注入远程接口方面存在问题。正如错误所示,它正试图为SessionServiceImpl注入本地接口,但这不会发生,因为ejb容器(基于ejb规范)只公开了一个远程接口,因为SessionServiceImpl实现了SessionService,并且没有使用@LocalBean注释

      关于ejb3.1的注释:

      • 如果会话bean实现除Serializable之外的任何接口, 可比较、可外部化,则实现的接口将 被认为是bean的远程接口
      • 此外,您还使用@EJB注释定义了远程 SessionServiceImpl的接口,因此它不位于 本地命名空间,但在远程命名空间中

      最后,从application.xml中删除
      true
      似乎是一个好办法。(). 另外,我不得不用
      @EJB

      替换一些
      @Inject
      注释,最后从application.xml中删除
      true
      ,这似乎是一个技巧。(). 另外,我不得不用
      @EJB

      替换一些
      @Inject
      注释。为什么不使用最新的8.2.1甚至9.0.1版本?你的问题很有可能已经解决了,这是一个很好的观点。最初的原因是我找不到适合EclipseKepler的服务器适配器,我不想花太多时间寻找它(因为它是低优先级任务)。但是你是对的,我将尝试迁移到9.0.1你总是可以在Jboss工具项目下找到最新的WildFly/Jboss adapters for eclipse是的,但是现在我可以看到,只有WildFly 8.0是受支持的。8.2和9应该也可以工作。你为什么不使用最新的8.2.1甚至9.0.1版本?你的问题很有可能已经解决了,这是一个很好的观点。最初的原因是我找不到适合EclipseKepler的服务器适配器,我不想花太多时间寻找它(因为它是低优先级任务)。但是你是对的,我将尝试迁移到9.0.1你总能在Jboss工具项目下找到最新的WildFly/Jboss adapters for eclipse是的,但目前我可以看到,只有WildFly 8.0受支持。8.2和9也应该可以工作。谢谢你的解释。我现在成功地部署了这些以前失败的部件。我真的不知道为什么它现在开始工作:)谢谢你的解释。我现在成功地部署了这些以前失败的部件。我真的不知道为什么它现在开始工作:)