Java EE,Maven项目 - Glassfish4中的CDI部署失败

时间:2014-03-02 16:27:11

标签: maven java-ee cdi glassfish-4

我正在Java EE maven项目中工作,在尝试部署到Glassfish4服务器时,我遇到了依赖注入问题。

maven项目由顶层pom下的三个独立模块构成,如下所示:

克罗诺斯:

  • EJB
  • 网络

Kronos是父模块,web处理前端代码(JSF,ManagedBeans),ejb具有后端代码(EJB,JPA),耳朵处理耳部人工制品的生成和部署。实际的pom.xml文件列在本文末尾。

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

当尝试使用类型StaffDAO字段上的@Inject注释在Web组件中的ManagedBean(@ManagedBean,@ RequestScoped)中注入bean时,我们在尝试部署到Glassfish时出现以下错误:

    [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>

1 个答案:

答案 0 :(得分:2)

事实证明我原来的怀疑是正确的。因为Web模块依赖于ejb模块,所以ejb类被添加到war存档中。因为当耳朵是从战争和ejb jar构建的时候,那些类最终被打包两次并且混淆了CDI。

我通过制作第四个maven模块来修复它,以保存ejb和web模块所需的代码,将其作为依赖项添加到这两个模块并打破web对ejb的依赖。现在它工作正常。