我正在一個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>
我現在在看在GlassFish Web管理界面模塊和組件視圖,我看到StaffDAOImpl包括兩次。一旦在ejb-1.0-SNAPSHOT.jar,一次在網絡1.0 SNAPSHOT.war 我相信,這是由於這兩個耳朵和Web模塊依賴於EJB,但無論是除去依賴性打破構建。 我應該建立的第三組分保持爲EJB和Web模塊(接口,數據模型和異常類)或者是有不同的解決方案的共同代碼推薦? – Dalamar42
您可以嘗試使用您提供的EJB,並通過遠程查找它。我假設所有這些都是要在EAR內部署的,並且你所有的EJB引用都在EAR中,對嗎? –
這是正確的。我真的設法弄清楚了。原來問題是我懷疑的。 Web模塊依賴於ejb的事實意味着ejb類會被添加到耳朵包中兩次。一旦進入ejb罐,並在戰爭中一次。我將在下面發佈這個以及標記它,以便它可以幫助其他人。 – Dalamar42