I have a simple OmniFaces 1.8.3 view-scoped bean successfully deployed on WebSphere 7 (7.0.50) along with OpenWebBeans 1.2.8 (and Mojarra 2.1.27 BTW):
import java.io.Serializable;
import java.util.List;
import javax.annotation.PostConstruct;
import javax.ejb.EJB;
import javax.inject.Named;
import org.omnifaces.cdi.ViewScoped;
...
@Named
@ViewScoped
public class CashValueCalculationManager implements Serializable {
private static final long serialVersionUID = 1L;
@EJB
private CashValueCalculationService cashValueCalculationService;
// the list of entities to be shown in a datatable
private List<CashValueCalculation> entities;
@PostConstruct
public void init() {
// displays "this.cashValueCalculationService = null" in the log
System.out.println("this.cashValueCalculationService = " + this.cashValueCalculationService);
// load list of entities on init
try {
this.loadViewData();
} catch (Exception e) {
e.printStackTrace();
}
}
public List<CashValueCalculation> getEntities() {
return this.entities;
}
protected CashValueCalculationService getEntityService() {
return this.cashValueCalculationService;
}
protected void loadViewData() throws Exception {
// NPE here!
List<CashValueCalculation> cashValueCalculations = this.getEntityService().findAll();
this.entities = cashValueCalculations;
}
}
When opening the view of the bean however, the bean gets initialized running the @PostConstruct
method to load all entities (just a handful), but this fails with a NullPointerException
in loadViewData(). The returned service is null... this basically gets confirmed by the log in which I also find the line
this.cashValueCalculationService = null
The CashValueCalculationService
interface is annotated with @Local
and the implementation CashValueCalculationServiceBean
is annotated with @Stateless
:
@Local
public interface CashValueCalculationService extends EntityService<Integer, CashValueCalculation> {
// super interface has findAll()
}
Bean:
@Stateless
public class CashValueCalculationServiceBean extends BaseEntityServiceBean<Integer, CashValueCalculation> implements CashValueCalculationService {
// super class has findAll() implementation
}
I had this successfully being injected into JSF managed beans before trying the OmniFaces/CDI/OpenWebBeans on WebSphere 7 craze.
When app gets deployed on the server the following log entries appear:
.
.
.
[13.07.17 16:56:13:889 CEST] 00000013 WebContainerL I OpenWebBeans Container is starting...
[13.07.17 16:56:13:894 CEST] 00000013 PluginLoader I Adding OpenWebBeansPlugin : [OpenWebBeansJsfPlugin]
[13.07.17 16:56:13:899 CEST] 00000013 AbstractMetaD I added beans.xml marker: wsjar:file:/C:/IBM/WebSphere7.0/AppServer/profiles/CLDSrv7050/installedApps/srv-cld-helNode03Cell/CLD.ear/lib/omnifaces-1.8.3.jar!/META-INF/beans.xml
[13.07.17 16:56:13:901 CEST] 00000013 AbstractMetaD I added beans.xml marker: file:/C:/IBM/WebSphere7.0/AppServer/profiles/CLDSrv7050/installedApps/srv-cld-helNode03Cell/CLD.ear/cld-web.war/WEB-INF/beans.xml
[13.07.17 16:56:15:051 CEST] 00000013 AbstractMetaD W Ignoring class [org.omnifaces.facesviews.FacesViewsInitializer] because it could not be loaded: java.lang.NoClassDefFoundError: javax.servlet.ServletContainerInitializer
[13.07.17 16:56:15:322 CEST] 00000013 AbstractMetaD W Ignoring class [org.omnifaces.component.output.cache.CacheInitializerListener] because it could not be loaded: java.lang.NoClassDefFoundError: javax.servlet.FilterRegistration
[13.07.17 16:56:15:328 CEST] 00000013 AbstractMetaD W Ignoring class [org.omnifaces.util.Platform] because it could not be loaded: java.lang.NoClassDefFoundError: javax.servlet.ServletRegistration
[13.07.17 16:56:15:581 CEST] 00000013 AbstractMetaD W Ignoring class [org.omnifaces.facesviews.FacesViewsInitializer] because it could not be loaded: java.lang.NoClassDefFoundError: javax.servlet.ServletContainerInitializer
[13.07.17 16:56:15:586 CEST] 00000013 AbstractMetaD W Ignoring class [org.omnifaces.component.output.cache.CacheInitializerListener] because it could not be loaded: java.lang.NoClassDefFoundError: javax.servlet.FilterRegistration
[13.07.17 16:56:15:588 CEST] 00000013 AbstractMetaD W Ignoring class [org.omnifaces.util.Platform] because it could not be loaded: java.lang.NoClassDefFoundError: javax.servlet.ServletRegistration
[13.07.17 16:56:16:438 CEST] 00000013 AbstractMetaD W Ignoring class [org.omnifaces.facesviews.FacesViewsInitializer] because it could not be loaded: java.lang.NoClassDefFoundError: javax.servlet.ServletContainerInitializer
[13.07.17 16:56:16:443 CEST] 00000013 AbstractMetaD W Ignoring class [org.omnifaces.component.output.cache.CacheInitializerListener] because it could not be loaded: java.lang.NoClassDefFoundError: javax.servlet.FilterRegistration
[13.07.17 16:56:16:446 CEST] 00000013 AbstractMetaD W Ignoring class [org.omnifaces.util.Platform] because it could not be loaded: java.lang.NoClassDefFoundError: javax.servlet.ServletRegistration
[13.07.17 16:56:17:199 CEST] 00000013 BeansDeployer I All injection points were validated successfully.
[13.07.17 16:56:17:236 CEST] 00000013 WebContainerL I OpenWebBeans Container has started, it took [3345] ms.
[13.07.17 16:56:17:291 CEST] 00000013 config I Mojarra 2.1.27 ( 20140108-1632 https://svn.java.net/svn/mojarra~svn/tags/2.1.27@12764) für Kontext '/cld' wird initialisiert.
[13.07.17 16:56:17:739 CEST] 00000013 application I JSF1048: PostConstruct/PreDestroy-Annotationen vorhanden. Verwaltete Bean-Methoden, die mit diesen Annotationen markiert sind, lassen die entsprechenden Annotationen verarbeiten.
[13.07.17 16:56:19:334 CEST] 00000013 config W JSF1067: Ressource /WEB-INF/common-ui.taglib.xml, die von der Konfigurationsoption javax.faces.CONFIG_FILES angegeben wird, kann nicht gefunden werden. Die Ressource wird ignoriert.
[13.07.17 16:56:19:336 CEST] 00000013 config W JSF1067: Ressource /WEB-INF/common-functions.taglib.xml, die von der Konfigurationsoption javax.faces.CONFIG_FILES angegeben wird, kann nicht gefunden werden. Die Ressource wird ignoriert.
[13.07.17 16:56:19:475 CEST] 00000013 PostConstruct I Running on PrimeFaces 6.0.15
[13.07.17 16:56:19:478 CEST] 00000013 VersionLogger I Using OmniFaces version 1.8.3
[13.07.17 16:56:19:497 CEST] 00000013 lifecycle I JSF1027: [null Die ELResolvers für JSF wurden nicht im JSP-Container registriert.
.
.
.
The entries
Ignoring class [org.omnifaces.facesviews.FacesViewsInitializer] because it could not be loaded: java.lang.NoClassDefFoundError: javax.servlet.ServletContainerInitializer
Ignoring class [org.omnifaces.component.output.cache.CacheInitializerListener] because it could not be loaded: java.lang.NoClassDefFoundError: javax.servlet.FilterRegistration
Ignoring class [org.omnifaces.util.Platform] because it could not be loaded: java.lang.NoClassDefFoundError: javax.servlet.ServletRegistration
appear to the most interesting ones.
But what do they actually mean?
Of course, it's somewhat clear, the servlet.api
classes are missing.
<dependency org="javax.servlet" name="servlet-api" rev="2.5" />
(Sorry this is Ant/Ivy syntax)
However adding javax-servlet-api-2.5.jar
to the deployment totally breaks the app when logging in, saying "FacesServlet is not a Servlet class":
In HTML:
Original Exception:
Error message: javax.servlet.UnavailableException: SRVE0201E: Servlet [javax.faces.webapp.FacesServlet] is not a servlet class.
Error code: 404
Target servlet: Faces Servlet
Stacktrace:
javax.servlet.UnavailableException: SRVE0201E: Servlet [javax.faces.webapp.FacesServlet] is not a servlet class.
at com.ibm.ws.webcontainer.servlet.ServletWrapper.handleRequest(ServletWrapper.java:535)
at com.ibm.ws.webcontainer.servlet.ServletWrapper.handleRequest(ServletWrapper.java:503)
at com.ibm.ws.webcontainer.servlet.ServletWrapperImpl.handleRequest(ServletWrapperImpl.java:181)
at com.ibm.ws.webcontainer.webapp.WebApp.handleRequest(WebApp.java:3954)
at com.ibm.ws.webcontainer.webapp.WebGroup.handleRequest(WebGroup.java:276)
at com.ibm.ws.webcontainer.WebContainer.handleRequest(WebContainer.java:942)
at com.ibm.ws.webcontainer.WSWebContainer.handleRequest(WSWebContainer.java:1592)
at com.ibm.ws.webcontainer.channel.WCChannelLink.ready(WCChannelLink.java:186)
at com.ibm.ws.http.channel.inbound.impl.HttpInboundLink.handleDiscrimination(HttpInboundLink.java:453)
at com.ibm.ws.http.channel.inbound.impl.HttpInboundLink.handleNewRequest(HttpInboundLink.java:515)
at com.ibm.ws.http.channel.inbound.impl.HttpInboundLink.processRequest(HttpInboundLink.java:306)
at com.ibm.ws.http.channel.inbound.impl.HttpICLReadCallback.complete(HttpICLReadCallback.java:83)
at com.ibm.ws.tcp.channel.impl.AioReadCompletionListener.futureCompleted(AioReadCompletionListener.java:165)
at com.ibm.io.async.AbstractAsyncFuture.invokeCallback(AbstractAsyncFuture.java:217)
at com.ibm.io.async.AsyncChannelFuture.fireCompletionActions(AsyncChannelFuture.java:161)
at com.ibm.io.async.AsyncFuture.completed(AsyncFuture.java:138)
at com.ibm.io.async.ResultHandler.complete(ResultHandler.java:204)
at com.ibm.io.async.ResultHandler.runEventProcessingLoop(ResultHandler.java:775)
at com.ibm.io.async.ResultHandler$2.run(ResultHandler.java:905)
at com.ibm.ws.util.ThreadPool$Worker.run(ThreadPool.java:1646)
I had to translate the error message as best as I could. WebSphere 7 BTW is a Servlet 2.5 container, so the problem might be classloader-related... ?
BIG QUESTION(s):
Why is this setup failing to inject EJBs via @EJB
on the basically usable scenario (without the javax.servlet
dependency)? The bean and bean manager seem to be present, so why isn't it able to inject via @EJB
?
How do you possibly cure this? Can it be done at all?
WAS-7 implements the JavaEE 5 standard. This did not include CDI yet. That means that there is also no integration between EJB and CDI.
What you can do is to write a CDI Extension which uses ProcessAnnotatedType and for all CDI classes you create a custom programmatic Bean per found @EJB. This custom Bean simply looks up the EJB via JNDI and that's it.
If you only need this a few times then you could also use a @PostConstruct method and fetch the EJB from the JNDI context directly in the class.