Reading the documentation of redhat (https://access.redhat.com/site/documentation/en-US/JBoss_Enterprise_Application_Platform/6/html/Development_Guide/chap-Class_Loading_and_Modules.html) I found that the application server classloader
has a priority list when loading classes that are used to avoid any conflict between
loaded classes, The order is as below
Implicit dependencies.
These are the dependencies that are added automatically by JBoss Enterprise Application Platform 6, such as the JAVA EE APIs. These dependencies have the highest class loader precedence because they contain common functionality and APIs that are supplied by JBoss Enterprise Application Platform 6.
Refer to Section 3.7.1, “Implicit Module Dependencies” for complete details about each implicit dependency.
Explicit dependencies.
These are dependencies that are manually added in the application configuration. This can be done using the application's MANIFEST.MF file or the new optional JBoss deployment descriptor jboss-deployment-structure.xml file.
Refer to Section 3.2, “Add an Explicit Module Dependency to a Deployment” to learn how to add explicit dependencies.
Local resources.
Class files packaged up inside the deployment itself, e.g. from the WEB-INF/classes or WEB-INF/lib directories of a WAR file.
Inter-deployment dependencies.
These are dependencies on other deployments in a EAR deployment. This can include classes in the lib directory of the EAR or classes defined in other EJB jars.
I tried to test this order by using a JSF webapp (rich faces) in my EAR archive
My ear is as below :
sample.ear
--- sport.war
--- mysql.jar
--- lib
Usescase 1 : I added the JSF jars under the webapp (sport.war/WEB-INF/lib): [jsf-api-2.1.14.jar/jsf-impl-2.1.14.jar/portletbridge-api-3.1.2.Final.jar/portletbridge-impl-3.1.2.Final.jar], the jboss server started well and I don't have any exception
Usescase2: I added the JSF jars under sample.ear/lib
==> When I start the jboss server I get an exception (it sounds that the application server loaded the module JSF provided by jboss Implicit dependencies instead of the one in my sample.ear/lib)
I can't understand why in the 1srt usescase the Class Loading Precedence is not respected while in the 2sd usescase the Class Loading Precedence is respected?
Could you please clarify me this point
ENV
JBoss EAP 6.1.0.GA (AS 7.2.0.Final-redhat-8)
JDK 6
Without seeing the exact deployment exception that you got it is difficult to diagnose the issue.
In the first scenario the packaged libraries are loaded in the same class loader as your application.
In the second scenario the packaged libraries are loaded in a separate module and class loader.
The above means that , The deployment issue you were having fo not have to be related to Class Loading Precedence they could also be related to Class Loading Isolation.
Also Jboss and EAP already come with a prepackaged implementation of JSF, and you might be experiencing collisions due to version mismatch
If you were looking to replace the default JSF implementation on JBoss the better option to do so would have been to put the new JSF implementation in a static module, just like the default one , and have Jboss load it on demand.
Related
In a JSF/facelet page, I'm trying to call a method with an enum value as a parameter, like this:
<f:viewAction action="#{myController.myMethod('MY_ENUM_VALUE')}" />
The code is working correctly using Tomcat but when trying with Websphere, this is not working anymore and I get the following exception.
Caused by: javax.el.MethodNotFoundException: /myPage.xhtml #16,24 action="#{myController.myMethod('MY_ENUM_VALUE')}": Method not found: com.example.MyController#807f4c26.myMethod(java.lang.String)
at com.sun.faces.facelets.el.TagMethodExpression.invoke(TagMethodExpression.java:109)
I'm wondering if there is a simple solution (configuration in Websphere?) or if I should integrate a different EL implementation in my WAR to override the one of Websphere. Any other suggestion is also welcome.
Additional information:
Websphere 8.5, using Mojarra 2.2.5 implementation (override implementation of Websphere, using PARENT_LAST mode)
Using Spring (with the SpringBeanFacesELResolver configured in faces-config.xml)
I'm not packaging any special EL implementation in the EAR/WAR.
Tomcat does not provide a JSF implementation so you are free to provide any version compatible with the servler/JSP version provided by your Tomcat server.
However, WebSphere AS 8.5 is a full Java EE 6 application server that integrates JSF into the container.
Bundling libraries into a WAR that are contained in the server does not automatically override the server libraries. Java defaults to a parent-first class loading model. Some of the configuration information available in arbitrary enterprise libraries may not make sense to the container and result in undefined behavior. Additionally, deployment descriptors can specify the loading of WAR-specific libraries that are not necessarily compatible with the container.
Some containers (WebSphere among them) support parent-last class loading. This can result in so much weird behavior it should generally be avoided.
As far as I am aware there is only one documented way to support a com.sun.faces... JSF implementation and I suspect in is only temporarily there to support WAS 7 binary JSF app WAR files.
So, it is possible that you are not really overriding the platform implementation but are triggering some undefined behavior by bundling JSF libraries in the WAR file.
It is possible I've missed something about what you are doing; if so, provide more details.
I am trying to deploy an application on Websphere 8.5.5
I've created a shared library for Websphere that includes myfaces 2.2 jars and other dependencies like commons-collections.
I also made the class loader of my application as PARENT_LAST.
When I deploy the application, I get this exception:
An error occured while initializing MyFaces: Class com.ibm.ws.jsf.config.annotation.WASMyFacesAnnotationProvider is no org.apache.myfaces.spi.AnnotationProvider
java.lang.IllegalArgumentException: Class com.ibm.ws.jsf.config.annotation.WASMyFacesAnnotationProvider is no org.apache.myfaces.spi.AnnotationProvider
at org.apache.myfaces.shared.util.ClassUtils.buildApplicationObject(ClassUtils.java:557)
at org.apache.myfaces.shared.util.ClassUtils.buildApplicationObject(ClassUtils.java:524)
I was looking at running a newer version of MyFaces on WAS 8.5.5, and ran into a similar issue. It appears to be a conflict between the code IBM wrote to support its embedded version of MyFaces, and an application- or shared library-provided MyFaces.
IBM provides a way to circumvent this issue. When WAS 8.0 shipped, it provided a feature to allow select either "SunRI1.2" or "MyFaces" as the server-provided JSF. Setting the default to "SunRI1.2" would remove the server-provided MyFaces from the classpath and allow the developer to provide their own.
Select any application
Click JSP and JSF Options
In the JSF implementation section, change the drop-down to SunRI1.2
Click OK
Save configuration and restart server
I'd like to use <p:calendar> in my JSF app developed in Netbeans, so I added the PrimeFaces library. However, when I deploy the app, it errors as follows:
Context with name [/ManagedBeansWithComponents] has not yet been started
C:\Users\Dell-pc\Documents\NetBeansProjects\ManagedBeansWithComponents\nbproject\build- impl.xml:1040: The module has not been deployed.
See the server log for details.
BUILD FAILED (total time: 1 second)
And the server log says:
Source Document: jar:file:/C:/Users/Dell-pc/Documents/NetBeansProjects/ManagedBeansWithComponents/build/web/WEB-INF/lib/primefaces-3.5.jar!/META-INF/faces-config.xml
Cause: Class 'org.primefaces.component.fileupload.FileUploadRenderer' is missing a runtime dependency: java.lang.NoClassDefFoundError: org/apache/commons/fileupload/FileItem
How is this caused and how can I solve it?
java.lang.NoClassDefFoundError: org/apache/commons/fileupload/FileItem
There is the cause. It's crystal clear. The mentioned class is missing in the runtime classpath. The solution is rather straightforward: put the mentioned class (or, the JAR file containing it) in the runtime classpath. As the package name hints, it's available on http://commons.apache.org/fileupload (which in turn has by the way http://commons.apache.org/io as dependency). Just download and drop those JARs in the same place as PrimeFaces JAR and all should be well.
Unrelated to the concrete problem, note that this particular problem is in turn unintented by PrimeFaces. This problem should actually only occur when you register the FileUploadFilter for the <p:fileUpload> component in web.xml. However, since GlassFish 4.0, it is overzealously preloading every single JSF component and renderer class found in the classpath even if it's never used by the application. The class loading in turn causes all its runtime dependencies to be checked. If it's missing, then you get the NoClassDefFoundError. This problem is thus specific to GlassFish 4.0 and does not occur when using GlassFish 3.x or any other servletcontainer such as Tomcat or JBoss.
I have made a jsf 1.1 portlet in weblogic 10.3, but in one scenario I need tomahawk library help. I just dropped the jar file and supporting ones in lib folder in WEB-INF in my portal application, but when I hit the url it gives me error of NoClassdef..... exception for classes in tomahawk jar and jsp compilation fails.
I am new to weblogic, I'll really appreciate if someoe can suggest what I might be doing wrong.
The setup is that whole application goes as ear. Ear contains app-inf and weblogic specific xml files, main portal web application goes as war inside this ear. I am using workshop that ships with weblogic portal 10.3. Well this project was migrated from weblogic portal 9.3.
Note: I dont want to but this jar in domain/lib, when I did so I dont know why it loaded my application and all the class defined in servlet startup with load-on-startups got fired well before time and none of the classes were found by server.
Jsf libraries currently used are in shared mode.
java.lang.NoClassDefFoundError means the runtime version of the class in the classpath is not the same as that at compile time.
Note: it's not a ClassNotFoundException.
Your problem is in fact multiple versions of the class being found.
Also, JSF 1.2 libraries are bundled with Weblogic server, so it can cause this exception if one of those classes is again added into the WEB-INF/lib. Which is the exact class on which the error is thrown, do you have multiple versions of Tomahawk lying around in WEB-INF and domain/lib?
Remove the extras and keep one in WEB-INF/lib only.
Update:
The docs state that Separate JSF 1.2 and JSTL 1.2 JAR files and implementation JAR files are also provided in the WL_HOME/server/lib/api.jar file.
Check for that class javax/faces/webapp/UIComponentELTag in this jar.
I still think you should use the weblogic.xml setting to force the WEB-INF/lib class to get loaded in preference to that in server/lib with
<container-descriptor>
<prefer-web-inf-classes>true</prefer-web-inf-classes>
</container-descriptor>
Being new to weblogic and infrastructure I messed up with different versions. Figured out it was just because of incompatible jars.
JSF 1.1 and websphere 6.1 was working properly in my case. Once I deployed that to a websphere 7 server, I received the following error -
Application was not properly initialized at startup, could not find Factory: javax.faces.context.FacesContextFactoryat javax.faces.FactoryFinder.getFactory(FactoryFinder.java:270)
at javax.faces.webapp.FacesServlet.init(FacesServlet.java:164)
at com.ibm.ws.webcontainer.servlet.ServletWrapper.init(ServletWrapper.java:358)
at com.ibm.ws.webcontainer.servlet.ServletWrapperImpl.init(ServletWrapperImpl.java:168)
Not sure what it means, I have enabled JSF1.2 as project facet in the RAD but still keep getting the above error message and none of my jsf files are working.
EDIT
After following BalusC's comment, I see the following directories are lookup by the code (this is the o/p of url.getPath())
/C:/IBM/SDP/runtimes/base_v7/profiles/AppSrv01/properties/
/C:/IBM/SDP/runtimes/base_v7/properties/
/
/C:/IBM/SDP/runtimes/base_v7/java/lib/
/C:/IBM/SDP/runtimes/base_v7/lib/
/C:/IBM/SDP/runtimes/base_v7/deploytool/itp/plugins/com.ibm.etools.ejbdeploy/runtime/
/C:/IBM/SDP/runtimes/base_v7/installedConnectors/sib.api.jmsra.rar/
/C:/IBM/SDP/runtimes/base_v7/installedConnectors/wmq.jmsra.rar/
/C:/DETSphere10/DET_FALL9.0/DETEJB/classes/
/C:/DETSphere10/DET_FALL9.0/.metadata/.plugins/org.eclipse.wst.server.core/tmp0/DETWEB/
There is no jsf impl in among these directories. Now I am more confused as the original lib should be present under c:\IBM\SDP\runtimes\base_v7\plugins !!
This is a typical error when there are multiple different versioned JSF libraries in the classpath. Websphere ships with builtin JSF libraries. If you'd like to use the webapp-supplied JSF libraries, then you need to set the classloading policy to module after deploying. This usually defaults to application which means that the webapp libraries are loaded by the main classloader. The main classloader may happen to have loaded the JSF API library. When its version is different from the JSF IMPL library in the webapp, then you may receive this kind of errors.
Update to help with nailing down the root cause better here are 2 suggestions:
You can reveal all used classpath roots on the local disk file system as follows:
for (URL url : Collections.list(Thread.currentThread().getContextClassLoader().getResources(""))) {
System.out.println(url.getPath());
}
Execute this in ServletContextListener#contextInitialized() or so.
(eventually after finding that out), install WinRAR, associate it with JAR file type and use its file-search facility to search for a JSF specific file like FacesContext.class and FacesContextImpl.class so that you can find all JAR's which contains the JSF API/impl. You can find out the exact JSF version by extracting the JAR and reading the MANIFEST file.
You need to keep the JSF JAR's (icu4j.jar and jsf-ibm.jar if you are using IBM's component library) in your /WEB-INF/lib folder.