无法将@Stateless EJB注入CDI bean(多模块)Jakarta EE 8



将遗留项目迁移到Jakarta EE 8(Maven EAR在Wildly 26上构建(我正在努力将依赖性注入从我的实体模块(EJB封装(转移到WAR模块,Maven项目结构为:

-WebApp.ear
-WebApp-entities.jar
-WebApp-ejb.jar
-WebApp-web.war
-WebApp-mobile.war
-WebApp-api.war

该结构是基于wildfly-jakartaee8-with-tools原型创建的

我要注入的DAO是一个@Stateless bean,它使用@LocalBean没有接口,例如

@Named
@LocalBean
@Stateless
@TransactionAttribute(TransactionAttributeType.REQUIRED)
public class UserDAO extends GenericDAOBean<User,Long> {
@PersistenceContext(unitName="ReadOnlyDatabase")  private EntityManager readOnlyEntityManager;

/**
* Default constructor
*/
public UserDAO() {
//Super call to construct AbstractDAO
super();
}

public User findNonDeletedByEmail(String email){
String s = "from User where email = :email and disabled = false";
Query query = this.getEntityManager().createQuery(s);
query.setParameter("email", email);
try{
return (User)query.getSingleResult();
}catch(NoResultException nre){
return null;
}catch(Exception e){
return null;
}
}

}

我的CDIBean是WAR模块中的一个标准@RequestScoped bean,它试图注入DAO来执行登录

@Named
@RequestScoped
public class LoginBean implements Serializable {

private static final long serialVersionUID = 1504441323094295359L;
@Inject private SecurityContext securityContext;
@Inject private UserDAO userDAO;
@Inject private FacesContext facesContext;
@Inject private ExternalContext externalContext;
private String username, password;
public void login() throws IOException {

Credential credential = new UsernamePasswordCredential(username, new Password(password));

User user = userDAO.findByEmailForUserLogin(username);
AuthenticationStatus status = securityContext.authenticate(
getRequest(facesContext),
getResponse(facesContext),
AuthenticationParameters.withParams()
.credential(credential));

switch (status) {
case SEND_CONTINUE:
facesContext.responseComplete();
break;
case SEND_FAILURE:
facesContext.addMessage(null,
new FacesMessage(FacesMessage.SEVERITY_ERROR, "Login failed", null));
break;
case SUCCESS:
facesContext.addMessage(null,
new FacesMessage(FacesMessage.SEVERITY_INFO, "Login succeed", null));
externalContext.redirect(externalContext.getRequestContextPath() + "/user/home.xhtml");
break;
case NOT_DONE:
}

}
private static HttpServletResponse getResponse(FacesContext context) {
return (HttpServletResponse) context
.getExternalContext()
.getResponse();
}
private static HttpServletRequest getRequest(FacesContext context) {
return (HttpServletRequest) context
.getExternalContext()
.getRequest();
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}

}

当我从JSF页面调用login((方法时,我得到以下错误:

Target Unreachable, identifier 'loginBean' resolved to null: javax.el.PropertyNotFoundException

如果我注释掉了userDAO注入,方法调用ok,这样我就知道是userDAO导致了问题,没有其他错误

在服务器启动日志中,我可以看到UserDAO的注册情况良好,例如:

java:global/WebApp/Web-entities/UserDAO!com.webapp.dao.beans.UserDAO
java:app/Web-entities/UserDAO!com.webapp.dao.beans.UserDAO
java:module/UserDAO!com.webapp.dao.beans.UserDAO
java:global/WebApp/Web-entities/UserDAO
java:app/Web-entities/UserDAO
java:module/UserDAO

我在/web-inf/beans.xml(war(和/meta-inf/beans(jar(中定义了beans.xml,两者都带有bean-discovery-mode="annotated"

我的EJB模块作为maven依赖项包含在带有<scope>provided</scope>的WAR.pom中

我也尝试过使用@EJB进行注入。有相同的错误

更新:

我发现,通过在boss-deployment-structure.xml中设置<ear-subdeployments-isolated>false</ear-subdeployments-isolated>,可以进行注入,但这会导致依赖关系在模块之间重复和类路径错误,因此我认为这不是正确的解决方案(我们的遗留EE 6项目隔离了EAR部署,DI工作正常(

通过向jboss-deployment-structure.xml中的EJB和Entity模块添加模块依赖关系,最终实现了这一点,如下所示。。。

<sub-deployment name="WebApp-web.war">
<dependencies>
<module name="deployment.WebApp.ear.WebApp-entities.jar" />
<module name="deployment.WebApp.ear.WebApp-ejb.jar" />
</dependencies>
</sub-deployment>

注入WAR现在可以正常工作,这在遗留的EE 6/JBoss 7应用程序中是不需要的,所以类加载行为一定已经改变了

最新更新