JSF 2.0 app under Tomcat 6: "No Factories configured." - java

I am trying to run a JSF 2.0 webapp using Apache MyFaces 2.1.7 on a Tomcat 6 webserver. The App uses Tomahawk 1.1.11 and expression language 2.2 (el-impl-2.2.jar). For that purpose I've put the myfaces-api and myfaces-impl into Tomcats lib folder and exchanged Tomcats el-api.jar for the 2.2 variant.
When I call the first page of the app I always get the error:
java.lang.IllegalStateException: No Factories configured for this Application. This
happens if the faces-initialization does not work at all - make sure that you properly
include all configuration settings necessary for a basic faces application and that all
the necessary libs are included. Also check the logging output of your web application
and your container for any exceptions!
If you did that and find nothing, the mistake might be due to the fact that you use
some special web-containers which do not support registering context-listeners via TLD
files and a context listener is not setup in your web.xml.
A typical config looks like this;
<listener>
<listener-class>org.apache.myfaces.webapp.StartupServletContextListener</listener-class>
</listener>
javax.faces.FactoryFinder._getFactory(FactoryFinder.java:286)
javax.faces.FactoryFinder.getFactory(FactoryFinder.java:206)
javax.faces.webapp.FacesServlet.init(FacesServlet.java:116)
org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:293)
org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:859)
org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:602)
org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:489)
java.lang.Thread.run(Thread.java:679)
I definitely have the xml snippet mentioned in my web.xml. I tried to debug into the code and found that registeredFactoryNames on line 267 of javax.faces.FactoryFinder is empty which causes the error. I however do not understand why this is the case. What should be in there and how do I get it there?
The funny thing is that the webapp runs perfectly using embedded jetty 8. So it must be some dependency issue.
Hope someone with more insight into all of this can help me here.

Ok
I found the problem. The error results from having the myfaces-api.jar twice on your classpath. So for me the problem was I placed the myfaces-api.jar in the tomcat lib folder and in the WEB-INF/lib folder of the webapp.
While using an embedded tomcat with maven I had the myfaces-api.jar in the dependencies of the whole application and in the dependencies of the tomcat6-maven-plugin with scope compile both. I changed the scope from compile to provided in the global dependencies section and it worked.

I think it could be solved just adding an empty faces-config.xml file under /WEB-INF/ folder, to indicate the application uses JSF and MyFaces continue the initialization step. See the class org.apache.myfaces.ee6.MyFacesContainerInitializer for details.

Related

wildfly migration from AS 7 to WF10

I am new to WildFly Server. I am upgrading server from AS7 to Wildfly10. How to add JARS in WILDFLY10. In Error Log: i am getting missing Dependencies(Is this because of not reading JARS?).
you need to add jars like it is given on their wiki.
Sometimes you need to add a module (if it is a jar that is not
shipped with Wildfly and define it in
jboss-deployment-structure.xml).
Sometimes, in case it is already shipped (you may have to search inside the modules directory) and add it in jboss-deployment-structure.xml
Again it depends what is it saying. which dependency etc?
https://docs.jboss.org/author/display/WFLY10/Class+Loading+in+WildFly
Actually we need to delete the servlet-mappings in web.xml and use annotations to direct to java classes
1. #webservlet for Servlet classes.
2. #path for resources.
Also we need to delete some unneccessary jars, which wildfly have inbuilt.

JSF / Spring Security : view wrapper generates LinkageError

I'm having an issue with JSF rendering. Here's my setup:
CentOS
TomEE Plus 1.5.2
Icefaces
Spring Security 3
And my app is set up like this:
/opt/tomee/lib/[all the normal TomEE jars]
/opt/tomee/lib/[all the Spring Security jars]
/opt/tomee/lib/icefaces.jar
/opt/tomee/lib/icefaces-compat.jar
/opt/tomee/lib/icepush.jar
/opt/tomee/webapps/UI/index.xhtml
/opt/tomee/webapps/UI/WEB-INF/lib/icefaces-ace.jar
/opt/tomee/webapps/UI/[normal jsf 2 configuration]
There isn't anything obvious in the logs but when the JSF attempts to render I get the following error:
com/sun/crypto/provider/HmacCore
viewId=/index.xhtml
location=/opt/tomee/webapps/UI/index.xhtml
phaseId=RENDER_RESPONSE(6)
Caused by:
java.lang.LinkageError - com/sun/crypto/provider/HmacCore
at com.sun.crypto.provider.HmacSHA1.(DashA13*..)
The stack trace on the error page is massive, so I'm not going to dump a novel here, but here are the calls of note.
java.lang.LinkageError: com/sun/crypto/provider/HmacCore
at com.sun.crypto.provider.HmacSHA1.(DashA13*..)
{...}
at java.security.Provider$Service.newInstance(Provider.java:1221)
{...}
at org.apache.myfaces.shared.util.StateUtils.encrypt(StateUtils.java:328)
{...}
at org.icefaces.impl.renderkit.RenderWrapper.encodeEnd(RenderWrapper.java:53)
{...}
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:311)
I dumped the contents of all the jars in tomee/lib but com.sun.crypto isn't anywhere that I can find in the web server. Apps that don't use Spring Security work just fine.
Any thoughts?
OK. I got it to work so I'm going to be 'that guy' and answer my own question. I hope that it helps save someone else from the migraine it gave me. The problem went away after I did the following:
delete my war
let tomcat clean up the webapps dir
stop tomcat
delete the related directories from work
add the spring security taglibs jar to my app
remove the encoder declaration from my applicationSecurity.xml
rebuild the app
start tomcat
redeploy
drink heavily
profit
Step 10 wasn't actually a part of debugging process but I wouldn't have complained if it was. Share and enjoy.

Spring MVC configuration throws weird exception

I am trying to deploy a new spring MVC app, I've done it a dozen times, but now I run on a really weird error, can't even figure out what's happening:
My javaee-api is conflicting with the servlet-api. In the console it writes:
INFO: validateJarFile(E:\development\workspace\conference\src\main\webapp\WEB- INF\lib\javaee-api-6.0.jar) - jar not loaded. See Servlet Spec 2.3, section 9.7.2.
Offending class: javax/servlet/Servlet.class
Well, yes, it is a warning, but this jar is not loaded and I need it. Also, I have no servlet-api jars in my application libs, etc.
Also, the console throws such an exception:
SEVERE: Error configuring application listener of class com.sun.faces.config.ConfigureListener
java.lang.ClassNotFoundException: com.sun.faces.config.ConfigureListener
I mean, this jar is refered to the JSF and all of that stuff. I'm not using it at all, where should it try to get such a class? O_o
I am running the app on tomcat 7
Any ideas what is going on?
The problem with jar file is that Tomcat's classloader validates all clases, that it loads to JVM. In your case it faced a class from servlets API - javax.servlet.Servlet. You application code must not contain such classes inside WEB-INF/lib. These classes are shipped with servlet container itself. If you use maven, just change the scope of javax.servlet:servlet-api to provided.
After you fix this, try to reload the whole app, because it may occur that classloader just blocked javaee-api-6.0.jar entirely, not allowing any other classes be loaded from it.
You can remove the javaee-api-6.0.jar file from your webapps' WEB-INF/lib directory, by setting the scope provided in its dependency.
The Spec refers that the Servlet Container (Here, Tomcat) will supply the implementation classes of the Java EE spec. Having application specific implementations is a stability and security problem that is disallowed by the spec/Tomcat.
Thanks!

WAS 6 steps to follow to support MQ 7 features

I have problem with EAR module deployed in WAS6.
To support the MQ 7 features in my App. I follow the below steps:
Put Class loader policy as PARENT_LAST.
Placed all MQ 7 related jars in the root of EAR.
EAR contains Web module. When I try to start the application, I got following exception:
javax.servlet.jsp.JspException: Can't get definitions factory from context.
at org.apache.struts.taglib.tiles.InsertTag.processDefinitionName(InsertTag.java:575)
at org.apache.struts.taglib.tiles.InsertTag.createTagHandler(InsertTag.java:474)
at org.apache.struts.taglib.tiles.InsertTag.doStartTag(InsertTag.java:436)
at com.ibm._jsp._home._jspx_meth_tiles_insert_0(_home.java:106)
at com.ibm._jsp._home._jspService(_home.java:81)
The War contains the following jars.
xstream-1.3.1.jar,xercesImpl.jar, xalan.jar,struts.jar, standard.jar,commons-validator.jar, commons-net-1.4.0.jar, commons-fileupload.jar, commons-digester.jar, commons-collections.jar, commons-beanutils.jar,resolver.jar,jstl.jar, jfreechart-1.0.2.jar, jcommon-1.0.5.jar, jaxen-full.jar, jakarta-oro.jar.
EAR contains the following Jars,
com.ibm.mqjms.jar, com.ibm.mq.jmqi.jar, com.ibm.mq.jar, com.ibm.mq.headers.jar, com.ibm.mq.commonservices.jar,log4j.jar,dhbcore.jar.
And I set the class-path attribute in my Manifest file of the WAR with log4j.jar
Please anyone suggest me how Websphere's classloading policy works for where I went wrong.
Karthik
Some time ago I did something similiar. I wanted to use a specific version of a library which was already used within the WebSphere Application Server. That is the reason why you have to put your libraries in the EAR file and set the application server to PARENT_LAST class loader order.
Correct me if I am wrong, but you also have to specify your custom MQ client libraries in Manifest of your WAR file. You only mentioned Log4J. It should look somehting like this:
Class-Path: com.ibm.mqjms.jar com.ibm.mq.jmqi.jar [...] log4j.jar
Anyway, you can always check what libraries are in the Classpath of you application if you log into the Integrated Solutions Console (aka Admin Console) and check the Troubleshooting section. There is a classloader viewer. Just click yourself through the tree and check which library path are mentioned and which you would expect.
Finally, as Dylan already mentioned in his comment: WebSphere Application Server version 6.1 runs out of support September 30, 2012. :)

Controlling the classpath in a servlet

My servlet application includes a number of library .jars, some of which contain embedded log4j.xml or log4j.properties files. I'd like to ensure that log4j finds my log4j.xml first! I've tried searching for some specification of the priorities of the various classpath elements in a servlet (e.g. does WEB-INF/classes always precede WEB-INF/lib?), or some way to configure or tweak the servlet's classloader so that a given resource directory appears early in the classpath. So far, I've drawn a blank. Any suggestions on ensuring that a servlet .war file loads the correct log4j.xml via the classloader?
Tomcat 8.5
Ditto Tomcat 8.0.
See documentation: Class Loader HOW-TO.
Tomcat 8.0
The answer is simple, taken from the Tomcat documentation page, Class Loader HOW-TO. In particular notice the use of the /WEB-INF/ directory/folder.
Therefore, from the perspective of a web application, class or resource loading looks in the following repositories, in this order:
Bootstrap classes of your JVM
/WEB-INF/classes of your web application
/WEB-INF/lib/*.jar of your web application
System class loader classes (described above)
Common class loader classes (described above)
If the web application class loader is configured with <Loader delegate="true"/> then the order becomes:
Bootstrap classes of your JVM
System class loader classes (described above)
Common class loader classes (described above)
/WEB-INF/classes of your web application
/WEB-INF/lib/*.jar of your web application
Tomcat 6
Excerpted from Tomcat 6 page, Class Loader HOW-TO.
Therefore, from the perspective of a web application, class or resource loading looks in the following repositories, in this order:
Bootstrap classes of your JVM
System class loader classes (described above)
/WEB-INF/classes of your web application
/WEB-INF/lib/*.jar of your web application
$CATALINA_HOME/lib
$CATALINA_HOME/lib/*.jar
As far as I understand the resource selection from the classpath is non-deterministic (from the point of view of the app developer). Even if the same file is loaded consistently the behaviour could change:
1. When you upgrade the version of your current container.
2. If you switch containers.
The simplest solution will be to remove embedded log4j config files from library jars. It is almost never a good idea to embed log4j config's as it leads to the problem you are seeing here...
Are they third party jars or jars you developed?
We the Spring Log4jConfigListener in our web.xml file.
You can specify as a context parameter the location of the log4j config file, i.e. you could set it as /WEB-INF/log4j.xml
Would this be an option for you? If you're not using Spring I know that you can set the Log4j location programatically which might also work.
In my experience, WEB-INF/classes typically takes precedence over jars in WEB-INF/lib, however, that also depends on the servlet container you use (I could never figure out the behavior of JRun, for instance). It would help immensely if you could tell me which container you're using.
Also, are you certain that the offending log4j configuration is in a jar in WEB-INF/lib? Typically, when I've run into classpath problems in a servlet container situation, it's because of libraries that reside outside of the web app.
The servlet specs recommend that web app classloaders load their own classes before delegating to the container's classloader (SRV.9.7.2), but since this is counter to the Java spec, not all vendors do this by default (in fact Tomcat is the only container I've used that does this by default). With that said, it's always possible to configure your container's web app classloading behavior. If you tell me which container you're using, I may be able to help you (specifically, I have done this successfully before on WebLogic, WebSphere, Glassfish and JRun)).
If you're unable to control the classpath, since Tomcat is setting it for you, are you at least able to set a system property for log4j.configuration? I believe that location pointed to by that property can be set outside of the classpath.
If not, another approach, although an ugly one, would be to explicitly run one of the configurators yourself in your application code.
You need to have log4j.properties in your CLASSPATH. The best place is under WEB-INF/classes.
You also have to make sure that you use your version of log4j.jar. So, put it in WEB-INF/lib, just to make sure you are not using one from tomcat folders, since it may cause strange classloading issues.

Categories