Building a custom component library

In my last post I showed you how to combine the composite component collapsiblePanel with a classic component to make it really self-contained and reusable. As a next step, it would be nice to have this component in a jar file. In this post I will take reusability to the next level and show you how to build a custom component library with JSF 2.

Basically, all we have to do is put the artefacts of our component in a jar file. In our case this would be the folder of the resource library jsflive and the component class CollapsiblePanel.

First, we put class CollapsiblePanel into the jar file. As the component is registered with @FacesComponent no xml configuration is necessary. However, we still need an empty faces-config.xml in the jar. JSF only scans for annotations in jar files having a faces-config.xml. This file must be placed in the META-INF folder with the name faces-config.xml or a name ending with .faces-config.xml. The following listing shows the empty config file.

<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>

Second, we move the resource library jsflive into the folder /META-INF/resources in the jar file. With this step finished, the composite component can already be used. Put the jar in the classpath of your application and declare a prefix for namespace http://java.sun.com/jsf/composite/jsflive. The following listing shows an example view.

<html xmlns="http://www.w3.org/1999/xhtml"
    xmlns:h="http://java.sun.com/jsf/html"
    xmlns:jl="http://java.sun.com/jsf/composite/jsflive">
<h:head>
  <title>JSFlive test page</title>
</h:head>
<h:body>
  <h:form id="form">
    <jl:collapsiblePanel id="panel">
      <f:facet name="header">Header</f:facet>
      <h:outputText value="Just some text."/>
    </jl:collapsiblePanel>
  </h:form>
</h:body>
</html>

As I talked about a custom component library in the beginning, our jar might one day be extended with classic components, converters or validators. For this case we need a taglib config file to define tags for those artefacts. With JSF 2 it is possible to import a composite component resource library into a taglib. All composite components in the library are then available under the namespace of the taglib.

For our example we simply create a taglib config with a namespace and the element composite-library-name with the name of our resource library folder. The following listing shows the complete taglib configuration file.

<facelet-taglib version="2.0" 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-facelettaglibrary_2_0.xsd">
  <namespace>http://jsflive.at/taglib</namespace>
  <composite-library-name>jsflive</composite-library-name>
</facelet-taglib>

JSF automatically loads taglib config files from jar files in the classpath on startup. All we have to do is give the file a name ending with .taglib.xml and place it in the META-INF folder.

With the above taglib config file we can change the namespace in the above example view to http://jsflive.at/taglib.

The following figure shows the structure of the jar file for our component library.

Now that the jar file is finished you probably want to use the component library in your applications. All you have to do is put the jar file in the classpath and declare a prefix for the namespace.

The source code for the presented example can be found in the Github repository collapsible03.

Update: JSF 2.2 will provide a new and more flexible way to add tags for composite components to custom tag libraries. It will be possible to define tags for specific composite components coming from different resource libraries. See my post on composite components in taglibs with JSF 2.2 for further information.

6 responses to “Building a custom component library

  1. Pingback: Ajaxify composite component collapsiblePanel | JSFlive: Michael Kurz's JSF Weblog

  2. Your post has been very much util for me. Greetings 😉

  3. Pingback: JSF 2.2: Composite components in taglibs | JSFlive: Michael Kurz's JSF Weblog

  4. Updated post with information for JSF 2.2.

  5. Warning: The page test.xhtml declares namespace http://jsflive and uses the tag jp:customPanel , but no TagLibrary associated to namespace.Warning: The page /test.xhtml declares namespace http://jsflive and uses the tag jp:customPanel , but no TagLibrary associated to namespace. Please check the namespace name and if it is correct, it is probably that your library .taglib.xml cannot be found on the current classpath, or if you are referencing a composite component library check your library folder match with the namespace and can be located by the installed ResourceHandler.

    Can you please let me know why this warning generating. More over the component not resolving to html

Leave a reply to kaleemsagard Cancel reply