JSF Mojarra 2.2 on Websphere 8.x - jsf

We have been running a JSF 1.2 application on Websphere 7 and 8 for years. We build our war with JSF bundled in it, and always set the classloader as PARENT LAST.
Having now upgraded to JSF 2.2 (and RF4 and PF4 - until migration is complete ), we are now facing issues deploying on the same server (WAS 8.0 as well as WAS 8.5).
We've now done a similar approach (with bundling JSF and PARENT LAST classloading). The application does start, it mentions initialization of Mojarra 2.2.11 , but on first page request, we get below error:
java.lang.reflect.UndeclaredThrowableException
at com.sun.proxy.$Proxy34.markResourceRendered(Unknown Source)
at org.richfaces.resource.ResourceFactoryImpl.createMappedResource(ResourceFactoryImpl.java:366)
at org.richfaces.resource.ResourceFactoryImpl.createResource(ResourceFactoryImpl.java:343)
at org.richfaces.resource.ResourceHandlerImpl.createResource(ResourceHandlerImpl.java:266)
at javax.faces.application.ResourceHandlerWrapper.createResource(ResourceHandlerWrapper.java:137)
at org.apache.myfaces.custom.captcha.CAPTCHAResourceHandlerWrapper.createResource(CAPTCHAResourceHandlerWrapper.java:83)
at org.apache.myfaces.tomahawk.resource.UncompressedResourceHandlerWrapper.createResource(UncompressedResourceHandlerWrapper.java:109)
at org.apache.myfaces.tomahawk.resource.UncompressedResourceHandlerWrapper.createResource(UncompressedResourceHandlerWrapper.java:61)
at com.sun.faces.renderkit.html_basic.ScriptRenderer.encodeEnd(ScriptRenderer.java:104)
at javax.faces.component.UIComponentBase.encodeEnd(UIComponentBase.java:919)
at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1863)
Caused by: java.lang.reflect.InvocationTargetException
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:60)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:37)
at java.lang.reflect.Method.invoke(Method.java:611)
at org.richfaces.application.ServiceTracker$1.invoke(ServiceTracker.java:153)
... 52 more
Caused by: java.lang.ExceptionInInitializerError
at org.richfaces.resource.external.ResourceTrackerForMyFaces.<init>(ResourceTrackerForMyFaces.java:58)
at org.richfaces.resource.external.ResourceTrackerImpl.getImplementation(ResourceTrackerImpl.java:86)
at org.richfaces.resource.external.ResourceTrackerImpl.markResourceRendered(ResourceTrackerImpl.java:67)
... 57 more
Caused by: java.lang.NoSuchMethodException: org.apache.myfaces.shared_impl.renderkit.html.util.ResourceUtils.isRenderedStylesheet(javax.faces.context.FacesContext, java.lang.String, java.lang.String)
at java.lang.Class.throwNoSuchMethodException(Class.java:356)
at java.lang.Class.getMethod(Class.java:1018)
at org.richfaces.resource.external.ResourceTrackerForMyFaces.<init>(ResourceTrackerForMyFaces.java:49)
... 59 more
I have obviously seen many suggestions of using a shared library, but I have similarly found that CDI is not supported when not using the default JSF implementation provided by websphere.
The preferred solution would obviously be to have a single deployment war, but I'm wondering if that's possible in websphere?
Also note that this application runs fine on weblogic and tomcat7

I've tracked this down to a bug in Richfaces, present in the most recent version 4.5.9, in class org.richfaces.resource.external.ResourceTrackerImpl.
That class determines which ResourceTracker to use (there are different classes for either Mojarra and Myfaces), but simply checks if some class from MyFaces is on the classpath. That is the case, but JSF has initialized as Mojarra.
Here's the new method, in which I prevent a class lookup of MyFaces if the used JSF implementation is Mojarra.
private ResourceTracker getImplementation() {
ResourceTracker tracker = externalResourceTracker.get();
if (tracker == null) {
Class<?> myfacesResUtilClass = null;
if (!MOJARRA_IMPLTITLE.equals(FacesContext.class.getPackage().getImplementationTitle())) {
for (String myFacesResourceUtilsClass : MYFACES_RESOURCE_UTILS_CLASSES) {
try {
myfacesResUtilClass = this.getClass().getClassLoader().loadClass(myFacesResourceUtilsClass);
break;
} catch (Exception e) {
LOG.debug("could not load myfaces resource utils class: " + myFacesResourceUtilsClass, e);
}
}
}
if (myfacesResUtilClass != null) {
externalResourceTracker.compareAndSet(null, new ResourceTrackerForMyFaces(myfacesResUtilClass));
} else {
externalResourceTracker.compareAndSet(null, new ResourceTrackerForMojarra());
}
tracker = externalResourceTracker.get();
}
return tracker;
}
It's solved, but it disturbs me quite a lot that, apart from the bug, this class even checks on a websphere specific class, showing how MyFaces has actually been adapted to work on Websphere, instead of the other way around.

Related

WebLogic 12.2.1.4 JSF 1.2 ELContext provokes null pointer on literal expressions

Jsf page with myFaces trinidad 1.2.15 ver JSF 1.2-20 could not be parsed due to expression evaluation error over ELContext. here is the stack
Caused by: java.lang.NullPointerException
at com.sun.el.ValueExpressionLiteral.getValue(ValueExpressionLiteral.java:79)
at org.apache.myfaces.trinidad.webapp.UIXComponentELTag.setProperty(UIXComponentELTag.java:135)
at org.apache.myfaces.trinidadinternal.taglib.html.HtmlHeadTag.setProperties(HtmlHeadTag.java:70)
at org.apache.myfaces.trinidad.webapp.UIXComponentELTag.setProperties(UIXComponentELTag.java:122)
at javax.faces.webapp.UIComponentELTag.createComponent(UIComponentELTag.java:230)
at javax.faces.webapp.UIComponentClassicTagBase.createChild(UIComponentClassicTagBase.java:513)
at javax.faces.webapp.UIComponentClassicTagBase.findComponent(UIComponentClassicTagBase.java:782)
at javax.faces.webapp.UIComponentClassicTagBase.doStartTag(UIComponentClassicTagBase.java:1354)
at org.apache.myfaces.trinidad.webapp.UIXComponentELTag.doStartTag(UIXComponentELTag.java:71)
at jsp_servlet._jsp._btwizard.__btwizardmain._jsp__tag2(__btwizardmain.java:648) ....
The problem was that the setProperty method of UIXComponentELTag by default passes a null argument for ElContext as this:
bean.setProperty(key, expression.getValue(null));
This is not supported on the version of elcontext that weblogic12 uses. We were not allowed to change the version of trinidad being used so we had to patch the library changing all the calls of getValue with
bean.setProperty(key, expression.getValue(FacesContext.getCurrentInstance().getELContext()));
We also found this problem on some clases that were generated from XML files like Color.xml, DateTime.xml and Number.xml, so we had to prevent them from being generated and provide our own implementation.

Omnifaces 2.5.1 and multiple WARs inside EAR

I have an application that works fine runing Omnifaces 2.5.1 Mojarra under Wildfly 10. This application have a multiple WARs but only one uses Omnifaces.
Today I tried to add Omnifaces to use in a second WAR inside the EAR. And I'm getting this exception:
Exception 0 :
org.jboss.weld.exceptions.DeploymentException: WELD-001408: Unsatisfied dependencies for type Long with qualifiers #Param
at injection point [BackedAnnotatedField] #Inject #Param private siscom.web.jsf.controller.PartnerDetailsController.id
at siscom.web.jsf.controller.PartnerDetailsController.id(PartnerDetailsController.java:0)
WELD-001475: The following beans match by type, but none have matching qualifiers:
- Producer Method [Long] with qualifiers [#BatchProperty #Any] declared as [[UnbackedAnnotatedMethod] #Produces #BatchProperty public org.jberet.creation.BatchBeanProducer.getLong(InjectionPoint)]
at org.jboss.weld.bootstrap.Validator.validateInjectionPointForDeploymentProblems(Validator.java:359)
at org.jboss.weld.bootstrap.Validator.validateInjectionPoint(Validator.java:281)
at org.jboss.weld.bootstrap.Validator.validateGeneralBean(Validator.java:134)
at org.jboss.weld.bootstrap.Validator.validateRIBean(Validator.java:155)
at org.jboss.weld.bootstrap.Validator.validateBean(Validator.java:518)
at org.jboss.weld.bootstrap.ConcurrentValidator$1.doWork(ConcurrentValidator.java:68)
at org.jboss.weld.bootstrap.ConcurrentValidator$1.doWork(ConcurrentValidator.java:66)
at org.jboss.weld.executor.IterativeWorkerTaskFactory$1.call(IterativeWorkerTaskFactory.java:63)
at org.jboss.weld.executor.IterativeWorkerTaskFactory$1.call(IterativeWorkerTaskFactory.java:56)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
My controller is:
#ViewScoped #Named
public class PartnerDetailsController implements Serializable {
#Inject
#Param
private Long id;
}
Note: Sometimes work fine, sometimes doesn't. When I restart the application works. If I restart again, not works.
You can't use #Param with multiple WARs containing Omnifaces packaged in an EAR. This is an interaction bug between CDI and OF.
Related blog post: http://balusc.omnifaces.org/2013/10/cdi-behaved-unexpectedly-in-ear-so.html
I have not tested it lately if it works in the latest version.

ICEfaces throws UnsupportedOperationException when registering OmniFaces Html5RenderKit

I tried to add OmniFaces HTML5 support to a project without success.
ICEFaces throws an severity error:
ICEfaces rendering required by icefaces-compat.jar components. Enable via <icecore:config render="true" />.
Error Renter code hereendering View[/index.xhtml]
So I added icecore:config render="true" but it didn't work, throws same error.
Not sure if it's a configuration mistake.
What I've done is add to web.xml:
<context-param>
<param-name>org.omnifaces.HTML5_RENDER_KIT_PASSTHROUGH_ATTRIBUTES</param-name>
<param-value>
javax.faces.component.UIInput=x-webkit-speech,x-webkit-grammar;
javax.faces.component.UIComponent=contenteditable,draggable
</param-value>
</context-param>
And in faces-config:
<factory>
<render-kit-factory>org.omnifaces.renderkit.Html5RenderKitFactory</render-kit-factory>
</factory>
If "factory" is removed from faces-config, the project works but without HTML5 support. It seems that HTML5 render kit overrides the icefaces's kit.
One other thing that makes me think it's a config mistake is that NetBeans underlines "placeholder" attribute in an h:inputText.
Indeed, as I suspected, ICEfaces thinks it's being the only JSF library in the webapp and is performing an immediate instanceof check on the FacesContext#getResponseWriter() without inspecting the wrapped ones. Here's an extract from ICEfaces' DOMContext class:
85 ResponseWriter responseWriter = facesContext.getResponseWriter();
86 DOMResponseWriter domWriter;
87 if (responseWriter instanceof DOMResponseWriter) {
88 domWriter = (DOMResponseWriter) responseWriter;
89 } else {
90 // domWriter = createTemporaryDOMResponseWriter(responseWriter, facesContext);
91 log.severe("ICEfaces rendering required by icefaces-compat.jar " +
92 "components. Enable via <icecore:config render=\"true\" />.");
93 throw new UnsupportedOperationException("ICEfaces rendering required.");
94 }
(note: starting at line 222 there's a similar block)
In theory, you could workaround this by explicitly registering the ICEfaces renderkit factory after the OmniFaces one in faces-config.xml. However, I couldn't find a RenderKitFactory in the ICEfaces source code who's responsible for creating the DOMRenderKit. It appears that ICEfaces thinks it's a JSF implementation by itself and altogether overriding the default JSF implementation's HTML_BASIC renderkit as follows in its /META-INF/faces-config.xml:
<render-kit>
<render-kit-id>HTML_BASIC</render-kit-id>
<render-kit-class>org.icefaces.impl.renderkit.DOMRenderKit</render-kit-class>
</render-kit>
All in all, ICEfaces doesn't make it possible anymore to wrap the render kits via a factory. This is not so nice. Note that the extracted source contains an outcommented line referencing createTemporaryDOMResponseWriter() which does its job -almost- right. Perhaps they couldn't figure why it didn't always work and left it for what it was. Too bad.
The workaround would be to copy the DOMContext class into your webapp, in its original package (once deployed, classes in /WEB-INF/classes have precedence over the ones in /WEB-INF/lib, so the custom copy would be loaded instead of the ICEfaces one) and change the code starting at line 85 as follows and remove the entire if-else block thereafter:
85 ResponseWriter responseWriter = facesContext.getResponseWriter();
86 DOMResponseWriter domWriter = findDOMResponseWriter(responseWriter);
(do the same for the block starting at line 222)
And add the following method:
private static DOMResponseWriter findDOMResponseWriter(ResponseWriter responseWriter) {
while (!(responseWriter instanceof DOMResponseWriter) && responseWriter instanceof ResponseWriterWrapper) {
responseWriter = ((ResponseWriterWrapper) responseWriter).getWrapped();
}
if (responseWriter instanceof DOMResponseWriter) {
return (DOMResponseWriter) responseWriter;
}
else {
throw new UnsupportedOperationException("ICEfaces rendering required");
}
}
That should do it for you.

can not find org.apache.myfaces.el.ValueBindingImpl class in myfaces-impl 2.1.6

I am working on a jsf migration project. In the process of migration to jsf 2.0, I have replaced myfaces-api-1.1.5 and myfaces-impl1.1.5 with myfaces-impl(2.1.6). I got the following Exception.
at org.jboss.as.server.deployment.DeploymentUnitPhaseService.start(DeploymentUnitPhaseService.java:121)
at org.jboss.msc.service.ServiceControllerImpl$StartTask.startService(ServiceControllerImpl.java:1824)
at org.jboss.msc.service.ServiceControllerImpl$StartTask.run(ServiceControllerImpl.java:1759)
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886) [:1.6.0_22]
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908) [:1.6.0_22]
at java.lang.Thread.run(Thread.java:662) [:1.6.0_22]
Caused by: java.lang.NoClassDefFoundError: org/apache/myfaces/el/ValueBindingImpl
at java.lang.Class.getDeclaredConstructors0(Native Method) [:1.6.0_22]
at java.lang.Class.privateGetDeclaredConstructors(Class.java:2389) [:1.6.0_22]
at java.lang.Class.getConstructor0(Class.java:2699) [:1.6.0_22]
at java.lang.Class.getConstructor(Class.java:1657) [:1.6.0_22]
at org.jboss.as.web.deployment.jsf.JsfManagedBeanProcessor.deploy(JsfManagedBeanProcessor.java:105)
at org.jboss.as.server.deployment.DeploymentUnitPhaseService.start(DeploymentUnitPhaseService.java:115)
... 5 more
Caused by: java.lang.ClassNotFoundException: org.apache.myfaces.el.ValueBindingImpl from [Module "deployment.ASSET.war:main" from Service Module Loader]
at org.jboss.modules.ModuleClassLoader.findClass(ModuleClassLoader.java:191)
at org.jboss.modules.ConcurrentClassLoader.performLoadClassChecked(ConcurrentClassLoader.java:361)
at org.jboss.modules.ConcurrentClassLoader.performLoadClassChecked(ConcurrentClassLoader.java:333)
at org.jboss.modules.ConcurrentClassLoader.performLoadClass(ConcurrentClassLoader.java:310)
at org.jboss.modules.ConcurrentClassLoader.loadClass(ConcurrentClassLoader.java:103)
... 11 more
When I try to find out ValueBindingImpl in the jar files, I am not able to find org.apache.myfaces.el.ValueBindingImpl in the myfaces-impl(2.1.6).. Is there any alternative?
It seems that your code is using MyFaces 1.1 specific implementation classes instead of the JSF 1.1 API classes. For example,
ValueBinding binding = new ValueBindingImpl(...);
instead of
ValueBinding binding = application.createValueBinding(...);
You'd need to fix the code to remove MyFaces 1.1 specific implementation classes.
Note that ValueBinding is deprecated since JSF 1.2, if you can, replace by ValueExpression.

why does mojarra 2.1 scan every other war on each module startup?

We have a huge EAR application with about 20 ejb-jar and war modules.
For each war module that Mojarra starts, it seems it is trying to scan annotation on every other war. Other wars are unavailable to the classloader, so I get lot of exceptions. It eventually starts anyway, but it clutters my logs with warnings, and I guess application startup time could be much less without this (+100 seconds).
To make it clear, I have following structure:
EAR
+- ejb1
+- ejb2
+- war1
+- war2
When Mojarra starts war1, it complains about missing classes from war2 (ClassNotFoundException).
I saw this when upgrading to Glassfish 3.1 (and thus, Mojarra 2.1).
I found the reason, and some workaround.
On Glassfish 3.1, which ships with Mojarra 2.1, classpath scanning is delegated to Glassfish. Now, Glassfish seems to give all classes of ear file instead of war. I opened http://java.net/jira/browse/JAVASERVERFACES-1995 for that (but it really seems to be a Glassfish bug, not JSF/Mojarra).
While waiting for a fix, I patched Mojarra like this : in com.sun.faces.config.ConfigManager.java, around line 834, I commented out some lines:
// if (provider instanceof DelegatingAnnotationProvider &&
// null != annotationScanner) {
// // This InjectionProvider is capable of annotation scanning *and*
// // injection.
// ((DelegatingAnnotationProvider)provider).setAnnotationScanner(annotationScanner,
// metadataGetter.getJarNames());
// scanUris = Collections.emptySet();
// } else {
// This InjectionProvider is capable of annotation scanning only
scanUris = metadataGetter.getAnnotationScanURIs();
// }
The logs are now much less verbose. It seems Glassfish is still scanning every classes, so I still get warnings like this:
[#|2011-03-18T13:47:05.019+0100|WARNING|oracle-glassfish3.1|javax.enterprise.system.container.web.org.glassfish.web.loader|_ThreadID=57;_ThreadName=Thread-1;|WEB9052: Unable to load class org.apache.myfaces.custom.inputTextHelp.HtmlTextHelpRenderer, reason: java.lang.ClassNotFoundException: org.apache.myfaces.custom.inputTextHelp.HtmlTextHelpRenderer|#]
But no stacktrace from Mojarra, which is already quite less verbose.

Resources