JSF2.0 - *.xhtml pages give 404-NotFound but *.jsp work okay? - java

I have Weblogic 10.3.5 installed. I deployed the JSF 2.0 war on the server. In my WebContent folder, I have *.xhtml and *.jsp files, which contain JSF2.0 xhtml and pure JSP code, respectively. When I navigate to http://localhost:7001/MyApp/NewFile123.xhtml, I get a 404 Not found error page. (Nothing informative on the Eclipse console). But http://localhost:7001/MyApp/NewFile.jsp works well and does what it's supposed to do.
I am not mixing JSF and JSP but just wanted to see if JSP is gonna work. I have the appropriate servlet-mapping for the XHTML files.
I also have these on my classpath:
glassfish.el_1.0.0.0_2-2.jar
glassfish.jsf_1.0.0.0_2-1-5.jar
glassfish.jstl_1.2.0.2.jar
javax.servlet_1.0.0.0_2-5.jar
Another interesting thing, when I try to edit the *.xhtml files, the auto-complete doesn't work. (i.e it won't autocomplete <h:outp. It used to when I was using Weblogic 12.1 which has JSF2.0 out of the box.
Edit: Here is the relevant part of web.xml
<servlet>
<servlet-name>Faces Servlet</servlet-name>
<servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>Faces Servlet</servlet-name>
<url-pattern>*.xhtml</url-pattern>
</servlet-mapping>
So why do I get a 404 when I try to navigate to a JSF page? Any suggestions?

I also have these on my classpath:
glassfish.el_1.0.0.0_2-2.jar
glassfish.jsf_1.0.0.0_2-1-5.jar
glassfish.jstl_1.2.0.2.jar
javax.servlet_1.0.0.0_2-5.jar
Remove all those container-specific libraries from your /WEB-INF/lib. They do not belong there at all, the container already ships with them. Your /WEB-INF/lib should contain only the webapp-specific libraries which are not shipped with the container.
Your problem is most likely caused by the fact that Weblogic 1.0.3.5 is a Servlet 2.5 container which already ships with JSF 2.0, but that you're supplying a JSF 2.1 library which requires Servlet 3.0. I don't use Weblogic, but I've read that 1.0.3.x requires some specific steps to get JSF 2.0 to work, see also this blog. Here's an extract of relevance:
Download and install one of the latest Oracle WebLogic Server 11g Rel 1 (10.3.3) Installers from OTN. (Give the ZIP Installer a try. Aweseome lightweight!)
Create a new sample domain (call it whatever you want) and start the admin server
Open the administration console (http://localhost:7001/console/)
deploy the JSF 2.0 library (Deployments - Install - wlserver_10.3\common\deployable-libraries\jsf-2.0.war
Find your favorite JSF 2.0 sample (I'll take the guessNumber thing from the mojarra-2.0.2 distribution)
Add a weblogic.xml file to the WEB-INF/ folder with the following content:
<?xml version="1.0" encoding="UTF-8"?>
<weblogic-web-app>
<library-ref>
<library-name>jsf</library-name>
<specification-version>2.0</specification-version>
<implementation-version>1.0.0.0_2-0-2</implementation-version>
<exact-match>true</exact-match>
</library-ref>
</weblogic-web-app>
Update as per the comments:
I now suspect that it may be because of the project settings. I created a Dynamic Web Project and chose JSF 1.2. On the next step, where it asked me for the JSF specification and implementation, I pointed him to those glassfish jsf2 jars. The default was 1.2. Maybe I shouldn't have done that?
That might have generated a JSF 1.2 compliant faces-config.xml which would force JSF 2.0 to run in JSF 1.2 modus. You need to redeclare the <faces-config> root declaration to comply JSF 2.0.
<faces-config
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-facesconfig_2_0.xsd"
version="2.0">

Related

Issues running my first JSF 2 application [duplicate]

I have some Facelets files like below.
WebContent
|-- index.xhtml
|-- register.xhtml
|-- templates
| |--userForm.xhtml
| `--banner.xhtml
:
Both pages are using templates from /templates directory. My /index.xhtml opens fine in browser. I get the generated HTML output. I have a link in /index.xhtml file to /register.xhtml file.
However, my /register.xhtml is not getting parsed and returns as plain XHTML / raw XML instead of its generated HTML output. All EL expressions in form of #{...} are displayed as-is instead of that their results are being printed. When I rightclick page in browser and do View page source, then I still see the original XHTML source code instead of the generated HTML output. For example, the <h:body> did not become a <body>. It looks like that the template is not being executed.
However, when I open the /register.xhtml like /faces/register.xhtml in browser's address bar, then it displays correctly. How is this caused and how can I solve it?
There are three main causes.
FacesServlet is not invoked.
XML namespace URIs are missing or wrong.
Multiple JSF implemenations have been loaded.
1. Make sure that URL matches FacesServlet mapping
The URL of the link (the URL as you see in browser's address bar) has to match the <url-pattern> of the FacesServlet as definied in web.xml in order to get all the JSF works to run. The FacesServlet is the one responsible for parsing the XHTML file, collecting submitted form values, performing conversion/validation, updating models, invoking actions and generating HTML output. If you don't invoke the FacesServlet by URL, then all you would get (and see via rightclick, View Source in browser) is indeed the raw XHTML source code.
If the <url-pattern> is for example *.jsf, then the link should point to /register.jsf and not /register.xhtml. If it's for example /faces/*, like you have, then the link should point to /faces/register.xhtml and not /register.xhtml. One way to avoid this confusion is to just change the <url-pattern> from /faces/* to *.xhtml. The below is thus the ideal mapping:
<servlet>
<servlet-name>facesServlet</servlet-name>
<servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>facesServlet</servlet-name>
<url-pattern>*.xhtml</url-pattern>
</servlet-mapping>
If you can't change the <url-pattern> to *.xhtml for some reason, then you probably would also like to prevent endusers from directly accessing XHTML source code files by URL. In that case you can add a <security-constraint> on the <url-pattern> of *.xhtml with an empty <auth-constraint> in web.xml which prevents that:
<security-constraint>
<display-name>Restrict direct access to XHTML files</display-name>
<web-resource-collection>
<web-resource-name>XHTML files</web-resource-name>
<url-pattern>*.xhtml</url-pattern>
</web-resource-collection>
<auth-constraint />
</security-constraint>
JSF 2.3 which was introduced April 2017 has already solved all of above by automatically registering the FacesServlet on an URL pattern of *.xhtml during webapp's startup. The alternative is thus to simply upgrade to latest available JSF version which should be JSF 2.3 or higher. But ideally you should still explicitly register the FacesServlet on only one URL pattern of *.xhtml because having multiple possible URLs for exactly the same resource like /register.xhtml, /register.jsf, /register.faces and /faces/register.xhtml is bad for SEO.
See also:
Set default home page via <welcome-file> in JSF project
Opening JSF Facelets page shows "This XML file does not appear to have any style information associated with it."
Sometimes I see JSF URL is *.jsf, sometimes *.xhtml and sometimes /faces/*. Why?
JavaServer Faces 2.2 and HTML5 support, why is XHTML still being used
Which XHTML files do I need to put in /WEB-INF and which not?
Our servlets wiki - to learn the mandatory basics about servlets
2. Make sure that XML namespaces match JSF version
Since introduction of JSF 2.2, another probable cause is that XML namespaces don't match the JSF version. The xmlns.jcp.org like below is new since JSF 2.2 and does not work in older JSF versions. The symptoms are almost the same as if the FacesServlet is not invoked.
<html lang="en"
xmlns="http://www.w3.org/1999/xhtml"
xmlns:f="http://xmlns.jcp.org/jsf/core"
xmlns:h="http://xmlns.jcp.org/jsf/html"
xmlns:ui="http://xmlns.jcp.org/jsf/facelets">
If you can't upgrade to JSF 2.2 or higher, then you need to use the old java.sun.com XML namespaces instead:
<html lang="en"
xmlns="http://www.w3.org/1999/xhtml"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:ui="http://java.sun.com/jsf/facelets">
But ideally you should always use the latest version where available.
See also:
Which XML namespace to use with JSF 2.2 and up
JSF tags not executed
Warning: This page calls for XML namespace http://xmlns.jcp.org/jsf/XXX declared with prefix XXX but no taglibrary exists for that namespace
3. Multiple JSF implementations have been loaded
One more probable cause is that multiple JSF implementations have been loaded by your webapp, conflicting and corrupting each other. For example, when your webapp's runtime classpath is polluted with multiple different versioned JSF libraries, or in the specific Mojarra 2.x + Tomcat 8.x combination, when there's an unnecessary ConfigureListener entry in webapp's web.xml causing it to be loaded twice.
<!-- You MUST remove this one from web.xml! -->
<!-- This is actually a workaround for buggy GlassFish3 and Jetty servers. -->
<!-- When leaving this in and you're targeting Tomcat, you'll run into trouble. -->
<listener>
<listener-class>com.sun.faces.config.ConfigureListener</listener-class>
</listener>
When using Maven, make absolutely sure that you declare the dependencies the right way and that you understand dependency scopes. Importantingly, do not bundle dependencies in webapp when those are already provided by the target server.
See also:
Configuration of com.sun.faces.config.ConfigureListener
How to properly install and configure JSF libraries via Maven?
Make sure that you learn JSF the right way
JSF has a very steep learning curve for those unfamiliar with basic HTTP, HTML and Servlets. There are a lot of low quality resources on the Internet. Please ignore code snippet scraping sites maintained by amateurs with primary focus on advertisement income instead of on teaching, such as roseindia, tutorialspoint, javabeat, baeldung, etc. They are easily recognizable by disturbing advertising links/banners. Also please ignore resources dealing with jurassic JSF 1.x. They are easily recognizable by using JSP files instead of XHTML files. JSP as view technology was deprecated since JSF 2.0 at 2009 already.
To get started the right way, start at our JSF wiki page and order an authoritative book.
See also:
Java / Jakarta EE web development, where do I start and what skills do I need?
What is the need of JSF, when UI can be achieved with JavaScript libraries such as jQuery and AngularJS

JSF and Libraries Unclarity

After some time spent with servlets and JSPs now i'm trying to learn something about JSF. I've learned the basics, made a couple of simple examples, have a basic ideea of the 'workflow' but I still can't understand what's with the javax.faces.webapp.FacesServlet thing.
<servlet>
<servlet-name>Faces Servlet</servlet-name>
<servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>Faces Servlet</servlet-name>
<url-pattern>*.jsf</url-pattern>
</servlet-mapping>
I know that "Faces Servlet" it's just an 'internal' name just for the XML and that it gets bind with a class, in this case: javax.faces.webapp.FacesServlet. But where is this class anyway?! I'm using Eclipse, created a new Dynamic Project, GlassFish 4.0 as Server, JSF 2.0 as Configuration (selected no library) and neither did I import any jar. How can it be working? And when I try to run the same thing with JBoss I must import a javax.faces-2.2.2.jar file.
Ok, the library might be already included in GlassFish since it works but... will I face any problems if I try to deploy my app on another server? Like JBoss or Websphere.
In a nutshell: what are the prerequisites when working with JSF technology :)
Thank you.
javax.faces.webapp.FacesServlet is a class that implements Servlet interface. In order to be recognized in your application, you should add it in the web.xml as a <servlet>. This is basically done in this configuration:
<servlet>
<servlet-name>Faces Servlet</servlet-name>
<servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
Now, we can refer to this class in the web.xml file using the Faces Servlet name. Next thing do to is define the URL that will be handled by this servlet. This is done in this configuration:
<servlet-mapping>
<servlet-name>Faces Servlet</servlet-name>
<url-pattern>*.jsf</url-pattern>
</servlet-mapping>
So, any GET or POST request to this application server that ends with jsf suffix will be handled by Faces Servlet. You can use other URL patterns for the servlet mapping. This is better explained here: JSF Facelets: Sometimes I see the URL is .jsf and sometimes .xhtml. Why?
will I face any problems if I try to deploy my app on another server? Like JBoss or Websphere?
If the application server is a Java EE 5 compliant server, then you will have access to this servlet by using Mojarra implementation in form of JSF 1.2. For Java EE 6 compliant servers this will be in Mojarra implementation in for of JSF 2.x (check the notes of the application server to know the exact version). Currently, with GlassFish 4, you get Mojarra for JSF 2.2.
In case the application server is not a Java EE compliant server e.g. Tomcat, you must add the libraries manually in WEB-INF/lib folder of your web application. Which libraries to add? Depending on the JSF version and its requirements (read further).
what are the prerequisites when working with JSF technology?
This is covered in StackOverflow JSF wiki. Taken from there:
Minimum requirements
JSF 1.0 and 1.1 requires a minimum of Servlet 2.4 / JSP 2.0 and Java 1.4.
JSF 1.2 works on Servlet 2.4, but requires a minimum of JSP/EL 2.1 which goes hand in hand with Servlet 2.5, so it after all requires Servlet 2.5. If you replace JSP 2.1 by Facelets 1.x as default view technology, then you can use JSF 1.2 on Servlet 2.4. It requires a minimum of Java 1.5.
JSF 2.0 which uses by default Facelets 2.x requires a minimum of EL 2.1 which goes hand in hand with Servlet 2.5, so it requires after all Servlet 2.5. If you supply your own EL 2.1 API/impl, then you can in theory run JSF 2.0 on Servlet 2.4. It requires a minimum of Java 1.5.
JSF 2.1 uses some Servlet 3.0 specific features, but is backwards compatible with Servlet 2.5. Those Servlet 3.0 features are optional.
JSF 2.2 requires a minimum of Servlet 3.0, because of the new file upload component which is internally using the standard Servlet 3.0 API without the need for 3rd party libraries. It requires a minimum of Java 1.6.
Examples of Servlet 2.4 containers are Tomcat 5.5.x, JBoss AS 4.x and Sun Java Application Server.
Examples of Servlet 2.5 containers are Tomcat 6.0.x, JBoss AS 5.x and GlassFish 2.x.
Examples of Servlet 3.0 containers are Tomcat 7.0.x, JBoss AS 6.x and 7.x and GlassFish 3.x.
Examples of Servlet 3.1 containers are Tomcat 8.0.x, WildFly 8.x, and GlassFish 4.x.

Servlet Mapping for Weblogic 8, How to?

I have a WAR file with a web application that has been deployed to a weblogic stream.
The JSP part works fine, but it can't find the servlets. Possible due to the lack of mapping in my web.xml file.
I was working fine on Tomcat 6, but can't seem to find using weblogic.
I used annotation #WebServlet("/actionOne") but this doens't seem to work.
I am a little confused about how to map these correctly via the web.xml file.
the servlets are .java files and located at WEB-INF/classes/com/foo/bar/
So far I have added the following the web.xml file but the servlet-mapping section has me confused.
<servlet>
<servlet-name>actionOne</servlet-name>
<servlet-class>com.foo.bar.actionOne</servlet-class>
</servlet>
<servlet>
<servlet-name>actionTwo</servlet-name>
<servlet-class>com.foo.bar</servlet-class>
</servlet>
Hopefully the above is correct, the next section I'm not sure how to use and would appreciate some help.
<servlet-mapping>
<servlet-name>actionOne</servlet-name>
<url-pattern>/actionOne</url-pattern>
</servlet-mapping>
The servlets are being called from the jsp via a Form action="actionOne"
My mapping was correct, it seems the issue was related to a different version of servlet.api in the weblogic modules folder. 2.5 instead of 3.0. This resolved the issue.

Migration from Weblogic to Apache Tomcat

I am migrating my project(uses servlets / jsp / jdbc / jndi) build on Weblogic 10c to an Apache Tomcat 7.0.22. I have managed to configure the ldap authentication server and also to replace the xxx-jdbc.xml used by weblogic. Now my problem is that i am trying to migrate the weblogic.xml file found in web Content/WEB-INF directory. The contents of the xml file are the following:
<?xml version = '1.0' encoding = 'UTF-8'?>
<weblogic-web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.bea.com/ns/weblogic/weblogic-web-app http://www.bea.com/ns/weblogic/weblogic-web-app/1.0/weblogic-web-app.xsd"
xmlns="http://www.bea.com/ns/weblogic/weblogic-web-app">
<security-role-assignment>
<role-name>REGISTERED_USER</role-name>
<principal-name>GROUP_NAME_FROM_LDAP</principal-name>
</security-role-assignment>
<session-descriptor>
<debug-enabled>false</debug-enabled>
<tracking-enabled>true</tracking-enabled>
<cookie-name>nameOfCookie</cookie-name>
<cookie-max-age-secs>-1</cookie-max-age-secs>
<url-rewriting-enabled>false</url-rewriting-enabled>
<encode-session-id-in-query-params>false</encode-session-id-in-query-params>
<sharing-enabled>false</sharing-enabled>
</session-descriptor>
<context-root>my_app_context_root</context-root>
<servlet-descriptor>
<servlet-name>FileDownload</servlet-name>
</servlet-descriptor>
</weblogic-web-app>
From top to bottom i have the security-role-assignment which maps users from an ldap group to have the REGISTERED_USER. The tag session-descriptor i think is self explained. Then there is my apps context root context-root. And then some servlet definition that is used to register the servlet to Weblogic (this is also defined in web.xml and i think this will not need any more handling).
So what is the best way to migrate this weblogic.xml file in my application?
In Tomcat, these things can be defined in a couple of different places.
For the security-role re-mapping, use the standard <security-role-ref> in web.xml to re-map role names.
If you are using a servlet-3.0-spec webapp, then many of your session- and cookie-related items are available via web.xml:
<session-config>
<cookie-config>
<name>nameOfCookie</name>
<max-age>-1</max-age>
</cookie-config>
<!-- just don't use "URL" to disable rewriting -->
<tracking-mode>COOKIE</tracking-mode>
</session-config>
Otherwise, you'll have to resort to some acrobatics. First, I'll assume that you are using a META-INF/context.xml file within your webapp for deployment to Tomcat.
Session cookie name
<Context sessionCookieName="nameOfCookie" />
Cookie max-age
Use the standard <session-config><session-timeout /> in web.xml. (Technically, this configures the max-age of the session, but the effect is the same: the cookie will essentially become invalid after the session expires. If you really need cookie max-age, read this thread: http://markmail.org/thread/u2ysiz3uxays2w4i)
Cookie debug/tracking are not supported by configuration. You will have to write your own Filter(s) to duplicate these features.
Disabling URL rewriting will require that you write a Filter that overrides HttpServletResponse.encodeURL and HttpServletResponse.encodeRedirectURL to be no-ops on their String arguments.

Having Issues Uploading WAR File to WebSphere 6.1

I'm trying to deploy a web service onto WebSphere using a WAR file, which I have been told directly is completely possible and has been done many times before. WebSphere allows me to upload the file, specify the context root, and even start the application. However, when I try to access it by specifying my underlying URIs, WebSphere 404s on me. The relatively useless error message displayed is:
Error 404: SRVE0202E: Servlet [Jersey REST Service]: com.sun.jersey.spi.container.servlet.ServletContainer was found, but is corrupt: SRVE0227I: 1. Check that the class resides in the proper package directory. SRVE0228I: 2. Check that the classname has been defined in the server using the proper case and fully qualified package. SRVE0229I: 3. Check that the class was transferred to the filesystem using a binary transfer mode. SRVE0230I: 4. Check that the class was compiled using the proper case (as defined in the class definition). SRVE0231E: 5. Check that the class file was not renamed after it was compiled.
I have checked my naming conventions, modified my web.xml according to this blog post, attempted packaging it into an ear file (which threw out its own errors when I tried to upload it), and am trying to figure out what configurations I might have wrong. Any ideas of what I could change to make this work?
Edit
Here is the relevant part of my web.xml file:
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.4"
id="WebAppId"
xmlns="http://java.sun.com/xml/ns/j2ee"
xsi="http://www.w3.org/2001/XMLSchema-instance"
schemalocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
<display-name>MYPROJECT'SDISPLAYNAME</display-name>
<servlet>
<servlet-name>Jersey REST Service</servlet-name>
<servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class>
<init-param>
<param-name>com.sun.jersey.config.property.packages</param-name>
<param-value>MYPROJECTNAME</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>Jersey REST Service</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
</web-app>
Another Edit
I'm using the newest release of Jersey- is that part of the problem?
Yet Another Edit
I'm pretty sure that's the entire problem. WebSphere 6.1 runs jdk1.5, and Jersey stopped supporting that after Jersey 1.2...
As you suspect your problem is lack for WebSphere support for Jersey (or rather JAX-RS).
I don't see JAX-RS in the list of supported APIs by WAS.
http://publib.boulder.ibm.com/infocenter/wasinfo/v6r1/index.jsp?topic=/com.ibm.help.ic.WS.doc/info_sching.html
WAS 6.1 runs on J2SE 1.5 (as seen in the URL above)
Specification or API Version 6.1
Java 2 Standard Edition (J2SE) specification J2SE 5
These probably are the reasons behind the errors that you get to see in your WAS 6.1
HTH
Manglu

Categories