Migrating a legacy project to Jakarta EE 8 (Maven EAR build on Wildly 26) I am struggling to get the dependancy injection working from my Entities module (EJB packaging) to WAR module, the maven project structure is:
-WebApp.ear
-WebApp-entities.jar
-WebApp-ejb.jar
-WebApp-web.war
-WebApp-mobile.war
-WebApp-api.war
The structure was created based on the wildfly-jakartaee8-with-tools archetype
My DAO to be injected is a @Stateless bean that uses @LocalBean no-interface eg.
@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;
}
}
}
My CDI bean is a standard @RequestScoped bean in the WAR module that is attempting to inject the DAO to perform login
@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;
}
}
When I call the login() method from JSF page I get the following error:
Target Unreachable, identifier 'loginBean' resolved to null: javax.el.PropertyNotFoundException
If I comment out the userDAO injection the method calls ok so I know its the UserDAO causing the problem, there are no other errors
In the server startup logs I can see that UserDAO is registered ok eg:
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
I have beans.xml defined in /web-inf/beans.xml (war) and /meta-inf/beans.xml (jar) both with bean-discovery-mode="annotated"
My EJB module is included as a maven dependancy in the WAR .pom with <scope>provided</scope>
I have also tried injecting using @EJB have the same error
UPDATE:
I found that by setting <ear-subdeployments-isolated>false</ear-subdeployments-isolated>
in boss-deployment-structure.xml allows injection to work however this then creates issues with dependancies being duplicated across modules and class-path errors so I don't think its the right solution (our legacy EE 6 project had EAR deployments isolated and the DI worked ok)