19

Is it possible to put JSF2 Facelets files with common content into a JAR to use it from other web applications inside e.g. <ui:composition template>, <ui:include src>, <cc:implementation>, etc? If yes, how can I achieve this? Is some extra configuration necessary?

BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
Fabio B.
  • 970
  • 2
  • 14
  • 29

4 Answers4

33

You can put common resources in the /META-INF/resources folder of the JAR which is to be treated like as /WEB-INF/resources folder of the WAR.

E.g.

CommonWebProject
 |-- META-INF
 |    |-- resources
 |    |    `-- common
 |    |         |-- css
 |    |         |    `-- some.css
 |    |         |-- js
 |    |         |    `-- some.js
 |    |         |-- images
 |    |         |    `-- some.png
 |    |         |-- components
 |    |         |    `-- somecomposite.xhtml
 |    |         |-- someinclude.xhtml
 |    |         `-- sometemplate.xhtml
 |    |-- faces-config.xml
 |    `-- MANIFEST.MF
 :

The resources of the JAR are then available as follows:

<... xmlns:common="http://xmlns.jcp.org/jsf/composite/common/components">
<h:outputStylesheet library="common" name="css/some.css" />
<h:outputScript library="common" name="js/some.js" />
<h:graphicImage library="common" name="images/some.png" />
<common:somecomposite />
<ui:include src="/common/someinclude.xhtml" />
<ui:composition template="/common/sometemplate.xhtml" />
...

If you want to trigger the JSF2 annotation scanner as well so that you can put @ManagedBean, @FacesValidator, @FacesConverter and consorts in that project as well, then create a JSF2 compatible /META-INF/faces-config.xml file:

<?xml version="1.0" encoding="UTF-8"?>
<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">
</faces-config>

The Facelets resource resolver is only necessary if the resources are not in /META-INF/resources for some reason, or when you're not using Servlet 3.0 but 2.5, or when you're using an early JBoss/JSF version which has bugs in META-INF resource resolving. See also How to create a modular JSF 2.0 application? for a concrete example.

BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
  • This approach has not worked on JBoss 6 (Mojarra 2.0.1). I've tested on Tomcat 7 and Glassfish 4, and both working. JBoss throws this exception: `java.io.FileNotFoundException org.apache.naming.resources.DirContextURLConnection.getInputStream(DirContextURLConnection.java:369)` – Rafael Orágio Jul 19 '13 at 16:49
  • Impressive! Now works like a charm! Thank you very much @BalusC. – Rafael Orágio Jul 19 '13 at 17:24
  • Hey @BalusC should I put JSF and other dependencies in my maven jar project? How do I make the IDE recognize the taglibs e everything else? – Fred Dec 04 '14 at 15:36
  • Is it appropriate to put the entire facelet in a jar from the JSF standpoint? I mean put the whole web-page xhtml file and specify a navigation-case for it in a faces-config. So, the actual web-page won't be packaged in the war-archive, but in the jar intead. Or it's better off creating a custom tag containing the same as the page and then use it, so that the web-page will be packaged in the war, but the actual content of that web-page will be in the jar (custom tag)? – St.Antario Aug 26 '15 at 12:13
4

Yes, you can extend com.sun.faces.facelets.impl.DefaultResourceResolver to provide resources to JSF.

One generic solution is as follows:

In your pom.xml add:

    <dependency>
        <groupId>com.intersult</groupId>
        <artifactId>jsf-desktop</artifactId>
        <version>1.1-SNAPSHOT</version>
    </dependency>

    <repository>
        <id>intersult-repo</id>
        <name>Intersult Repository</name>
        <url>https://intersult.com/svn/public/maven</url>
    </repository>

Or simply add https://intersult.com/svn/public/maven/com/intersult/jsf-desktop/1.1-SNAPSHOT/jsf-desktop-1.1-SNAPSHOT.jar to your /WEB-INF/lib folder.

In your web.xml add:

<context-param>
    <param-name>javax.faces.FACELETS_RESOURCE_RESOLVER</param-name>
    <param-value>com.intersult.jsf_desktop.util.ClassPathResourceResolver</param-value>
</context-param>

In any JAR inside the WAR place XHTML-Files under /META-INF/resources/<file.xhtml>

Access it via "http://<domain>/<web-root>/<jsf-servlet>/resource/<file.xhtml>" (eg. http://localhost/faces/resource/test.xhtml) and it will be rendered.

Tires
  • 1,529
  • 16
  • 27
1

First read here about the difference between war and jar in a similar question.

You will have to create EAR file and pack the wars together.

Community
  • 1
  • 1
Dejell
  • 13,947
  • 40
  • 146
  • 229
  • Ok, but what I don't understand is: can I put the .war in the library folder of a new web application and include the web pages from the .war into other pages? – Fabio B. Aug 23 '10 at 14:31
0

Maven

Note that, if you are using Maven to create a JAR, you should use the following folder to put your resources into:

src/main/resources/META-INF/resources/
Jasper de Vries
  • 19,370
  • 6
  • 64
  • 102