2014-03-02 64 views
0

我正在一个Java EE maven项目中工作,并且在尝试部署到Glassfish4服务器时遇到依赖注入问题。Java EE,Maven项目 - Glassfish4中的CDI部署失败

Maven项目分为三个独立的模块下一个顶层POM的结构,像这样:

克罗诺斯:

  • EJB
  • 网络

克罗诺斯是父模块,Web处理前端代码(JSF,ManagedBeans),ejb具有后端代码(EJB,JPA)耳朵处理耳朵的产生和部署。实际的pom.xml文件列在这篇文章的末尾。

在ejb模块内部,我们有一个StaffDAO接口和一个StaffDAOImpl无状态bean(注释@ javax.ejb.Stateless)。目前,这是代码中唯一的EJB bean,它当然是实现StaffDAO的唯一bean。

当尝试使用@Inject标注上类型的字段当试图部署到Glassfish的StaffDAO我们得到以下错误的Web组件中注入ManagedBean(@ManagedBean,@RequestScoped)里面的豆:

[glassfish 4.0] [SEVERE] [] [javax.enterprise.system.core] [tid: _ThreadID=35 _ThreadName=admin-listener(4)] [timeMillis: 1393775922183] [levelValue: 1000] [[ 
     Exception while loading the app : CDI deployment failure:WELD-001409 Ambiguous dependencies for type [StaffDAO] with qualifiers [@Default] at injection point [[BackedAnnotatedField] @Inject private managedbeans.DummyUserBean.staffDAO]. Possible dependencies [[Session bean [class persistence.dao.impl.StaffDAOImpl with qualifiers [@Any @Default]; local interfaces are [StaffDAO], Session bean [class persistence.dao.impl.StaffDAOImpl with qualifiers [@Any @Default]; local interfaces are [StaffDAO]]] 
    org.jboss.weld.exceptions.DeploymentException: WELD-001409 Ambiguous dependencies for type [StaffDAO] with qualifiers [@Default] at injection point [[BackedAnnotatedField] @Inject private managedbeans.DummyUserBean.staffDAO]. Possible dependencies [[Session bean [class persistence.dao.impl.StaffDAOImpl with qualifiers [@Any @Default]; local interfaces are [StaffDAO], Session bean [class persistence.dao.impl.StaffDAOImpl with qualifiers [@Any @Default]; local interfaces are [StaffDAO]]] 

使用@EJB注释,而不是给我们:

[glassfish 4.0] [SEVERE] [NCLS-CORE-00026] [javax.enterprise.system.core] [tid: _ThreadID=34 _ThreadName=admin-listener(3)] [timeMillis: 1393776686187] [levelValue: 1000] [[ 
    Exception during lifecycle processing 
java.lang.IllegalArgumentException: Cannot resolve reference [Remote ejb-ref name=managedbeans.DummyUserBean/staffDAO,Remote 3.x interface =persistence.dao.StaffDAO,ejb-link=null,lookup=,mappedName=,jndi-name=,refType=Session] because there are [2] ejbs in the application with interface persistence.dao.StaffDAO. 
Some of the possible causes: 
1. The EJB bean class was packaged in an ear lib library (or through any other library mechanism which makes the library visible to all component modules), this makes all the component modules include this bean class indirectly. 
2. The EJB bean class was packaged in a component module which references the EJB, either directly or indirectly through Manifest, WEB-INF/lib. 
The EJB bean class should only be packaged in the declaring ejb module and not the referencing modules. The referencing modules should only include EJB interfaces. 

我相信,虽然我不知道,这是由我们的人工制品产生一个错误,这导致StaffDAOImpl EJB被包装两次造成的,但我不够满足熟悉maven来确认和解决这个问题。任何帮助,将不胜感激。

代码:

StaffDAO:

public interface StaffDAO {...} 

StaffDAOImpl:

import javax.ejb.Stateless; 

@Stateless 
public class StaffDAOImpl implements persistence.dao.StaffDAO {...} 

DummyUserBean:

import javax.faces.bean.ManagedBean; 
import javax.enterprise.context.RequestScoped; 
import javax.inject.Inject; 

@ManagedBean(name = "dummyUserBean") 
@RequestScoped 
public class DummyUserBean { 

    @Inject 
    private StaffDAO staffDAO; 

    ... 
} 

的pom.xml的文件是:

克罗诺斯:

<?xml version="1.0" encoding="UTF-8"?> 
<project xmlns="http://maven.apache.org/POM/4.0.0" 
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
     xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 
    <modelVersion>4.0.0</modelVersion> 

    <groupId>kronos</groupId> 
    <artifactId>kronos</artifactId> 
    <packaging>pom</packaging> 
    <version>1.0-SNAPSHOT</version> 
    <modules> 
     <module>ejb</module> 
     <module>web</module> 
     <module>ear</module> 
    </modules> 

    <dependencies> 
     <dependency> 
      <groupId>javax</groupId> 
      <artifactId>javaee-api</artifactId> 
      <version>7.0</version> 
     </dependency> 
    </dependencies> 

    <properties> 
     <maven.compiler.source>1.7</maven.compiler.source> 
     <maven.compiler.target>1.7</maven.compiler.target> 
    </properties> 

    <build> 
     <finalName>HelloGlassfish4</finalName> 
    </build> 
</project> 

耳朵:

<?xml version="1.0" encoding="UTF-8"?> 
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
     xmlns="http://maven.apache.org/POM/4.0.0" 
     xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 
    <parent> 
     <artifactId>kronos</artifactId> 
     <groupId>kronos</groupId> 
     <version>1.0-SNAPSHOT</version> 
    </parent> 
    <modelVersion>4.0.0</modelVersion> 

    <artifactId>ear</artifactId> 
    <packaging>ear</packaging> 

    <dependencies> 
     <dependency> 
      <groupId>kronos</groupId> 
      <artifactId>ejb</artifactId> 
      <version>1.0-SNAPSHOT</version> 
      <type>ejb</type> 
     </dependency> 

     <dependency> 
      <groupId>kronos</groupId> 
      <artifactId>web</artifactId> 
      <version>1.0-SNAPSHOT</version> 
      <type>war</type> 
     </dependency> 
    </dependencies> 

    <build> 
     <plugins> 
      <plugin> 
       <groupId>org.glassfish.maven.plugin</groupId> 
       <artifactId>maven-glassfish-plugin</artifactId> 
       <version>2.1</version> 
       <configuration> 
        <glassfishDirectory>${local.glassfish.home}</glassfishDirectory> 
        <user>${local.glassfish.user}</user> 
        <passwordFile>${local.glassfish.passfile}</passwordFile> 
        <domain> 
         <name>${local.glassfish.domain}</name> 
         <adminPort>${local.glassfish.adminPort}</adminPort> 
         <httpPort>${local.glassfish.httpPort}</httpPort> 
        </domain> 
        <components> 
         <component> 
          <name>${project.artifactId}</name> 
          <artifact>target/${project.build.finalName}.ear</artifact> 
         </component> 
        </components> 
        <debug>true</debug> 
        <terse>false</terse> 
        <echo>true</echo> 
       </configuration> 
      </plugin> 

      <plugin> 
       <artifactId>maven-ear-plugin</artifactId> 
       <version>2.8</version> 
       <configuration> 
        <modules> 
         <webModule> 
          <groupId>kronos</groupId> 
          <artifactId>web</artifactId> 
         </webModule> 
         <ejbModule> 
          <groupId>kronos</groupId> 
          <artifactId>ejb</artifactId> 
         </ejbModule> 
        </modules> 
        <defaultLibBundleDir>lib</defaultLibBundleDir> 
       </configuration> 
      </plugin> 
     </plugins> 
     <finalName>kronos</finalName> 
    </build> 
</project> 

EJB:

<?xml version="1.0" encoding="UTF-8"?> 
<project xmlns="http://maven.apache.org/POM/4.0.0" 
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
     xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 
    <parent> 
     <artifactId>kronos</artifactId> 
     <groupId>kronos</groupId> 
     <version>1.0-SNAPSHOT</version> 
    </parent> 
    <modelVersion>4.0.0</modelVersion> 

    <artifactId>ejb</artifactId> 

    <dependencies> 
     <dependency> 
      <groupId>org.hibernate</groupId> 
      <artifactId>hibernate-entitymanager</artifactId> 
      <version>3.6.7.Final</version> 
     </dependency> 

     <dependency> 
      <groupId>org.postgresql</groupId> 
      <artifactId>postgresql</artifactId> 
      <version>9.2-1003-jdbc4</version> 
     </dependency> 

     <dependency> 
      <groupId>org.slf4j</groupId> 
      <artifactId>slf4j-api</artifactId> 
      <version>1.7.6</version> 
     </dependency> 

     <dependency> 
      <groupId>junit</groupId> 
      <artifactId>junit</artifactId> 
      <version>4.11</version> 
     </dependency> 

     <dependency> 
      <groupId>org.mockito</groupId> 
      <artifactId>mockito-all</artifactId> 
      <version>1.9.5</version> 
     </dependency> 

     <dependency> 
      <groupId>com.google.guava</groupId> 
      <artifactId>guava</artifactId> 
      <version>16.0.1</version> 
     </dependency> 

     <dependency> 
      <groupId>javax.validation</groupId> 
      <artifactId>validation-api</artifactId> 
      <version>1.0.0.GA</version> 
     </dependency> 

     <dependency> 
      <groupId>org.hibernate</groupId> 
      <artifactId>hibernate-validator</artifactId> 
      <version>4.1.0.Final</version> 
     </dependency> 

     <dependency> 
      <groupId>joda-time</groupId> 
      <artifactId>joda-time</artifactId> 
      <version>2.3</version> 
     </dependency> 


    </dependencies> 

    <build> 
     <plugins> 
      <plugin> 
       <groupId>org.apache.maven.plugins</groupId> 
       <artifactId>maven-surefire-plugin</artifactId> 
       <version>2.16</version> 
       <configuration> 
        <skipTests>true</skipTests> 
       </configuration> 
      </plugin> 

      <plugin> 
       <groupId>org.apache.maven.plugins</groupId> 
       <artifactId>maven-ejb-plugin</artifactId> 
       <version>2.3</version> 
       <configuration> 
        <ejbVersion>3.2</ejbVersion> 
        <archive> 
         <manifest> 
          <addClasspath>true</addClasspath> 
         </manifest> 
        </archive> 
       </configuration> 
      </plugin> 

      <plugin> 
       <groupId>org.apache.maven.plugins</groupId> 
       <artifactId>maven-compiler-plugin</artifactId> 
       <version>3.1</version> 
       <configuration> 
        <source>1.7</source> 
        <target>1.7</target> 
       </configuration> 
      </plugin> 
     </plugins> 
    </build> 
</project> 

网站:

<?xml version="1.0" encoding="UTF-8"?> 
<project xmlns="http://maven.apache.org/POM/4.0.0" 
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
     xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 
    <parent> 
     <artifactId>kronos</artifactId> 
     <groupId>kronos</groupId> 
     <version>1.0-SNAPSHOT</version> 
    </parent> 
    <modelVersion>4.0.0</modelVersion> 

    <artifactId>web</artifactId> 
    <packaging>war</packaging> 

    <dependencies> 
     <dependency> 
      <groupId>kronos</groupId> 
      <artifactId>ejb</artifactId> 
      <version>1.0-SNAPSHOT</version> 
     </dependency> 

     <dependency> 
      <groupId>org.primefaces</groupId> 
      <artifactId>primefaces</artifactId> 
      <version>4.0</version> 
      <type>jar</type> 
     </dependency> 
    </dependencies> 

    <build> 
     <plugins> 
      <plugin> 
       <groupId>org.apache.maven.plugins</groupId> 
       <artifactId>maven-war-plugin</artifactId> 
       <configuration> 
        <webXml>src\main\webapp\WEB-INF\web.xml</webXml> 
       </configuration> 
      </plugin> 
     </plugins> 
     <finalName>web</finalName> 
    </build> 
</project> 
+0

我现在在看在GlassFish Web管理界面模块和组件视图,我看到StaffDAOImpl包括两次。一旦在ejb-1.0-SNAPSHOT.jar,一次在网络1.0 SNAPSHOT.war 我相信,这是由于这两个耳朵和Web模块依赖于EJB,但无论是除去依赖性打破构建。 我应该建立的第三组分保持为EJB和Web模块(接口,数据模型和异常类)或者是有不同的解决方案的共同代码推荐? – Dalamar42

+0

您可以尝试使用您提供的EJB,并通过远程查找它。我假设所有这些都是要在EAR内部署的,并且你所有的EJB引用都在EAR中,对吗? –

+0

这是正确的。我真的设法弄清楚了。原来问题是我怀疑的。 Web模块依赖于ejb的事实意味着ejb类会被添加到耳朵包中两次。一旦进入ejb罐,并在战争中一次。我将在下面发布这个以及标记它,以便它可以帮助其他人。 – Dalamar42

回答

2

原来我原来的怀疑是正确的。因为Web模块依赖于ejb模块,所以ejb类被添加到战争档案中。正因为如此,当耳朵由战争和ejb罐子建造时,这些类最终被包装了两次,并且混淆了CDI。

我通过创建第四个maven模块来保存ejb和web模块所需的代码,将它作为依赖项添加到这两个代码中,并打破了Web对ejb的依赖关系,从而解决了这个问题。现在它工作正常。

+0

我总是标志着我的Web模块我的EJB的依赖作为提供以避免此问题。虽然我在实践中没有看到它。 – Brian