JSF (Java Server Faces) has been developed as Java standard. Nowadays it is under heavy criticism, generally the time of all those Java/XML web-frameworks is over, they have proven to be too complex and inflexible. If you investigate you find a lot of confusing information about JSF on the web, including an outdated homepage. Some people also have bad memories about the jump from version 1 to 2.
Nevertheless, because it was pronounced as "standard", a lot of companies relied on it, and these JSF applications have to be maintained and supported. Consequently this article describes, for learning purposes, how to create a basic JSF project in an Eclipse EE, built out of Maven dependencies. As you will see, not even this setup is simple.
I wouldn't have succeeded without the help of following web pages:
- https://github.com/javaserverfaces/mojarra
- http://hantsy.blogspot.com/2017/11/activating-cdi-in-jsf-23.html
- https://www.javacodegeeks.com/2016/02/creating-jsfcdi-maven-project-eclipse.html
- http://alibassam.com/deploying-jsf-2-3-application-tomcat-9
Preparations
1) Java 8 or newer should be installed on your machine.
2) You need to install an EE-Eclipse (enterprise-edition), I used version 2019-06 (4.12.0), this has about 350 MB. Enriching an SE-Eclipse (standard-edition) would take a lot of time (I gave up after an hour).
3) Download and install Tomcat 9.
Setup
Update: quickest build with Eclipse
- In a file explorer, create a simple Maven project directory structure (not a "dynamic web project" archetype!)
- Add
pom.xml
with JSF dependencies (see below) in its root directory- Run Maven build from commandline:
mvn package
- Import the project into Eclipse as "Maven project" (not as "Java project"!), and give Eclipse some time to process it
- Verify: open context menu "Properties" on the project and select "Project Facets", JSF 2.3 and Dynamic Web Module 4.0 should have been activated by Eclipse
1) In Eclipse, create a simple "New Maven Project"
Select to use no archetype, just set packaging to "war" (web archive). Ignore error messages until step 3.
Using "maven-archetype-webapp" would result in a WebContent folder instead of src/main/webapp, and the Maven structure would be duplicated there.
My Maven artifactId is jsfMavenEclipse
.
2) In "Project Properties", click on "Project Facets"
Activate
- "Dynamic Web Module" with version 4.0,
- "Java" with 1.8,
- "JavaServer Faces" with 2.3,
Click "Apply and Close".
3) Define dependencies in Maven pom.xml
- javax.servlet 4.0 (standard),
- javax.faces (Oracle Mojarra)
- weld-servlet-shaded (JBoss)
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>fri</groupId> <artifactId>jsfMavenEclipse</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>war</packaging> <dependencies> <dependency> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId> <version>4.0.0</version> <scope>provided</scope> </dependency> <dependency> <groupId>org.glassfish</groupId> <!-- Oracle --> <artifactId>javax.faces</artifactId> <version>2.3.9</version> </dependency> <dependency> <groupId>org.jboss.weld.servlet</groupId> <!-- Red Hat --> <artifactId>weld-servlet-shaded</artifactId> <version>3.1.2.Final</version> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>3.8.1</version> <configuration> <source>1.8</source> <target>1.8</target> </configuration> </plugin> </plugins> </build> </project>
4) Run Maven Build
Run Maven by Eclipse popup menu "Maven" - "Update Project".
In case you want to build your project by Maven command-line, you must use this line:
mvn package eclipse:eclipse -Dwtpversion=2.0
In that case you must delete the project from Eclipse and re-import it as Maven-project, because it is not a "Maven Project" any more after that command-line when you "Refresh" it in Eclipse. Also you must check the facets and versions in "Project Properties" once more, see above!
5) Check versions
Check that JSF version in src/main/webapp/WEB-INF/faces-config.xml
header is 2.3 (occurs two times!):
<?xml version="1.0"?> <faces-config xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-facesconfig_2_3.xsd" version="2.3"> </faces-config>
and servlet version in src/main/webapp/WEB-INF/web.xml
header is 4.0 (occurs two times!):
<?xml version="1.0"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd" version="4.0"> <servlet> <servlet-name>Faces Servlet</servlet-name> <servlet-class>javax.faces.webapp.FacesServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>Faces Servlet</servlet-name> <url-pattern>*.xhtml</url-pattern> </servlet-mapping> </web-app>
Adjust it manually when necessary. These files should have been generated by Eclipse on creating the project.
6) Create an annotated FacesConfig Java class
Create an arbitrarily named empty application-config Java class
in a package somewhere below src/main/java
,
annotated with @FacesConfig
and @ApplicationScoped
.
Mine is in src/main/java/fri/jsf/ApplicationFacesConfig.java
:
package fri.jsf; import javax.enterprise.context.ApplicationScoped; import javax.faces.annotation.FacesConfig; @FacesConfig @ApplicationScoped public class ApplicationFacesConfig { }
(Most likely this step will disappear in future.)
7) Create beans.xml
Create an empty src/main/webapp/WEB-INF/beans.xml
file
with schema beans_2_0.xsd
and
header attribute bean-discovery-mode="all"
.
<?xml version="1.0"?> <beans xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/beans_2_0.xsd" version="2.0" bean-discovery-mode="all"> </beans>
Without this, or without the FacesConfig class, you would get a
javax.faces.FacesException: Unable to find CDI BeanManager
exception on server startup.
8) Integrate Tomcat 9 in Eclipse
Use menu "New" - "Server" - "New Server". You will have to choose the Tomcat version and its installation directory (the unzipped downloaded archive). You don't need to add any webapp to it, this will happen automatically when first running the example app.
Result of this step would be that Eclipse Project Explorer shows Tomcat below the "Servers" root node.
9) Create a JSF example page
Create a hello.xhtml
web-page in src/main/webapp
folder,
select it (in Eclipse Project Explorer) and trigger menu "Run on Server", then choose Tomcat 9.
Now the page should display and work inside Eclipse!
<!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml" xmlns:h="http://xmlns.jcp.org/jsf/html"> <h:head> <title>Hello JSF</title> </h:head> <h:body> <h:outputLabel>Hello JSF!</h:outputLabel> </h:body> </html>
Select it (in Eclipse Project Explorer) and trigger menu "Run on Server", then choose Tomcat 9. Now the page should display inside Eclipse!
You can call the URL http://localhost:8080/jsfMavenEclipse/hello.xhtml
also from any browser on your machine.
This is now the project's file structure:
Deployment Verification
The Eclipse deployment to Tomcat sometimes fails silently. Following is the directory where Eclipse deploys to:
eclipse-workspace/.metadata/.plugins/org.eclipse.wst.server.core/tmp*/wtpwebapps/jsfMavenEclipse
Replaceeclipse-workspace
by the name of your Eclipse workspace folder. Thetmp*
folder could betmp0
ortmp1
or ..., always use the newest one!
Copy files and JARs manually when missing or out-of-date!
3 Kommentare:
pure gold :)
Thanks!
Hi fritzthecat,
I tried to fix the javax.faces.FacesException: Unable to find CDI BeanManager error in my Tomcat 9 / Weld 3.1.4 installation for quite some time now and it almost drove me crazy... With the help of your blog post, I was finally able to fix it. THANKS a lot for your post!
Cheers,
Marc
Kommentar veröffentlichen