Is it a MyFaces or Mojarra application? - jsf

An application is installed to WebSphere 8. I would like to know if there is any way to check if the application is using MyFaces or Mojarra and the version used.

Different ways for checking which vendor is it:
FacesContext.class.getPackage().getImplementationVendor(); returns vendor's name.
You could otherwise look into your classpath to find jsf jars, myfaces ones usually start with myfaces- prefix.
Sometimes some specific myfaces- params can be found in the web context (web.xml). You could search for them.
For the version, you can also retrieve its number from the FacesContext:
FacesContext.class.getPackage().getImplementationVersion();
That will return the major implementation version. To check the minor ones, see the second link attached, once you know the vendor.
It seems WebSphere 8 uses a MyFaces implementation by default. You could find the JSF implementation jar and open its MANIFEST.MF file, the implementation version must be stored there.
See also:
How to detect current JSF-Version?
Access JSF and Primefaces version numbers programatically

Related

Is there any way to use JSF 2.x in JSF1.2 environment

Is it possible to configure JSF2.x in JSF 1.2.I have to implement few loics using JSF2.1 + primefaces5.2 in JSF 1.2 environment.
If its possible what are the configurations required in web.xml and other configuration files.
I don't know whether this question is correct or not.I am new to JSF.
No you can't. For obvious reasons. Older versions do not support newer functionality and running two different versions at the same time is not supported

How to prevent JSF from initializing automatically?

When I create a web application from scratch and add jsf-api-2.2.11.jar and jsf-impl-2.2.11.jar to pom.xml (add them to apps classpath) and deploy it to Tomcat 7, JSf is initializing automatically:
INFO [j.e.r.w.j.config] - Mojarra 2.2.11 ( 20150505-0732 https://svn.java.net/svn/mojarra~svn/tags/2.2.11#14688) ..... initialized.
In older versions I used to start it declarativly by defining it in web.xml (listener+servlet). So I already commented them out and set "metadata-complete" to "true" (does that even stop classpath scanning?), but it is still loading.
In this case I dont want it to load, while leaving the Jars in classpath and i.e. the faces-config.xml in web-inf.
What is still triggering the initialization?
It's loaded via a Servlet 3.0 ServletContainerInitializer implementation in the JSF implementation JAR file (in case of Mojarra, it's the com.sun.faces.config.FacesInitializer). It will auto-register the FacesServlet on the URL patterns *.jsf, *.faces and /faces/* (JSF 2.3 will add *.xhtml to the list of URL patterns). Latest JSF 2.1 implementations and all JSF 2.2 implementations will do it when deployed to a Servlet 3.0 compatible container. For detail about this new Servlet 3.0 ServletContainerInitializer thing, head to this answer: ServletContainerInitializer vs ServletContextListener.
The right way to stop it is removing the JSF implementation from the dependencies (note that you do not need to remove the JSF API as well). You seem to not be making use of it in any way. After all, a properly designed web application should not have any JSF implementation specific dependencies. I only wonder, why exactly would you leave the JSF API in? Using a 3rd party JSF based library for non-JSF purposes? This might indicate and end up in other (architectural) problems.
Another way of stopping it is downgrading your web application to be Servlet 2.5 targeted by editing the <web-app> root declaration in web.xml accordingly to comply that version. But this has many other side effects which may not be desireable when the intent is to develop a Servlet 3.0 compatible web application.
The "listener" you're referring to is actually not necessary, it's only to workaround buggy containers with timing errors in parsing TLD files, such as early GlassFish v3 and Jetty versions. See also a.o. Configuration of com.sun.faces.config.ConfigureListener.

javaee-api-7.0 with JSF 2.2: f:ajax does not submit

I have a Spring 4.1.1, JSF 2.2.3, Primefaces 5.1 web application that run on Java 8 and Tomcat 8.
Everything worked perfectly until my colleague added the javaee-api-7.0 as a dependency for javax for ActiveMQ.
With this jar in, every ajax call doesn't submit data to the backend. For example filters on primefaces datadatable would always pass an empty value, ajax refresh wouldn't take into account processed fields, etc. If I remove the jar, everything start to work again.
Unfortunately the logs don't show any error, the output is exactly the same of when the jar is not included. I'm not sure also with which component the conflict is, I would assume JSF but I have no clue and I can't find any documentation online.
Everything worked perfectly until my colleague added the javaee-api-7.0 as a dependency for javax for ActiveMQ.
You're indeed not supposed to have that JAR in webapp's runtime classpath. This kind of library is supposed to be already provided by the target Java EE container. Examples of Java EE containers are WildFly, GlassFish, Liberty, TomEE, etc. You've there however Tomcat, which is a barebones servletcontainer supporting from the huge Java EE API only JSP, Servlet and EL APIs, on which you have to manually install every other Java EE artifact, such as JSF and JMS.
The javaee-api.jar contains ALL Java EE APIs, including the JSF API (which is of 2.2.0 version). In your case, this one apparently got precedence in classloading over the JSF API version which you already had in /WEB-INF/lib. This will only result in "odd" behavior, because the loaded JSF impl version doesn't match the loaded JSF API version.
You need to solve it differently. You need to install JMS in its own API/impl JAR files, exactly like as you already did for JSF, and thus absolutely not via a "global" javaee-api.jar file. In case of ActiveMQ, the JMS API is available in activemq-all.jar. Use that one instead. It covers everything needed in order to get ActiveMQ to run on Tomcat.
See also:
how to include javax.jms.* in eclipse?
How do I import the javax.servlet API in my Eclipse project?

Can a jetty 5 custom classloader exclude specific jar files in a war?

I've got a large code base that currently runs on JSF 1.1 on embedded Jetty 5.1.14 server (Servlet 2.4). I've managed to get a JSF 2.0.9 app running on this version of Jetty even though I'd expected to require servlet 2.5, and I add EL 2.1.2 & the JSF jar to WEB-INF/lib. This works on a jetty config that excludes JSF 1.1.
The production environment consists of a large number of war and jar files on a single server instance.
JSF 1.1 is currently in the server ext/lib folder, and in a single war file I'd like to include the JSF 2 jar in the WEB-INF/lib. This is not possible as the server JSF version will load first and cause classpath pollution.
However would it be possible to eliminate the JSF 1.1 jar loading in just the one war file with a custom classloader? The documentation seems to cater for the case of adding paths to the classpath rather than excluding things. I wasn't clear whether it's loaded in the context of the server as a whole or just the war.
A little more information: Another potential solution is to simply upgrade to Jetty 8 and JSF 2.1+. Apart from convincing management that this is a good idea, we use an old WebMethods7 version, this has a graphical layout tool that produces some XML that is translated by a Component Application Framework, which uses the JSF APIs to generate content (so only a very few JSPs). This would simply be a case of seeing if it works, and if not having a total rethink because of the need to keep supporting this WebMethods "code".
The main goal here is to ultimately run up to date software although not necessarily in one step.
Jetty5 is incredibly old at this point and I would recommend working on the update to jetty8, or waiting a couple of months and making the jump to jetty9 which we are currently releasing milestones for. Changes in the newer jvm's since then alone are enough reason to update your jetty container.
I don't know if this approach was supported in jetty5 or not, but in jetty6 we have ability on the webapp context to modify the classes that are exposed to the context via system and server classes. If those hooks exists then you should be able to tweak that specific context to not expose the classes in the jar in ext/lib.

Websphere 7 and JSF 1.2 - Application was not properly initialized at startup, could not find Factory

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.

Resources