4
votes

JSF spec 2.2 (2013-03-20) says in item 10.3.3.1 (Declaring a composite component library for use in a Facelet page):

If a facelet taglibrary is declared in an XHTML page with a namespace starting with the string “http://java.sun.com/jsf/composite/” (without the quotes), the remainder of the namespace declaration is taken as the name of a resource library [...]

If the substring following “http://java.sun.com/jsf/composite/” contains a “/” character, or any characters not legal for a library name the following action must be taken. If application.getProjectStage() is Development an informative error message must be placed in the page and also logged. Otherwise the message must be logged only.

So that means it's illegal to have the following folder structure:

resources
    components
        system
        something_specific
        something_even_more_specific

and refer to the library name “http://java.sun.com/jsf/composite/components/something_specific”? Is this correct?

That seems like a weird restriction. I want my sources structured, not mushed together in an enormous lump.

Such hierarchical library actually works in Wildfly 8.0.0.CR1, but I'm not sure if it's wise to rely on this behavior.

A "best practices" kind of answers are welcome.

2
Stumbled upon the following in the javax.faces.application.ResourceHandler.createResource(String) javadoc: For historical reasons, this method operate correctly when the argument resourceName is of the form libraryName/resourceName, even when resourceName contains '/' characters.Vsevolod Golovanov

2 Answers

2
votes

I'll summarize my findings.

Sources: JSF spec issue 740, discussion preceding issue 740, another discussion, JSF spec issue 1141, discussion preceding issue 1141.

Slash in a library name is disallowed. Slash in a resource name is allowed.

In practice on Mojarra 2.2.5 composite component library just works both in a XHTML namespace declaration, and in taglib's <composite-library-name>components/system</composite-library-name>. I expect that could still break in future Mojarra and/or JSF spec versions. If you use this, you're at JSF spec/impl developers' mercy. Linked issues and discussions have shown them to be willing to preserve backwards compatibility even for unintended features.

In MyFaces there is a special setting, org.apache.myfaces.STRICT_JSF_2_ALLOW_SLASH_LIBRARY_NAME (MyFaces issue 3454). I expect that relying on a resource library with slashes in its name, using this setting, could break some functionality such as JSF resource versioning (how can it know what part is a library name and what part belongs to resource name?).

I think composite component library hierarchy may be implemented by importing components in a taglib one by one:

<tag>
    <tag-name>test</tag-name>
    <component>
      <resource-id>
          components/system/test.xhtml
      </resource-id>
    </component>
</tag>

Thus the library name effectively becomes "components" and the resource name becomes "system/test.xhtml".

0
votes

after some experiment, i think that these statements should be read:

  • the remainder of the namespace declaration is taken as the name of a resource library http://java.sun.com/jsf/composite/components/system must match /resources/components/system

  • any characters not legal for a library name

    if you declare http://java.sun.com/jsf/composite/components/system2 and /resources/components/system2 does not exists, take action

    Warning: This page calls for XML namespace http://java.sun.com/jsf/composite/components/system2 declared with prefix y but no taglibrary exists for that namespace.

so it is absolutely legal to declare

xmlns:x="http://java.sun.com/jsf/composite/components/system"

and any other folder structure that exists under /resources