jakartaee / jakartaee/faces

Resource name with a query string is forbidden by the identifier grammar and required by the TCK

Open
#2,242 2 comments 0 reactions 0 assignees View on GitHub
EE12 mojarra-implemented
Dominant language
Java
Stars
127
Forks
59
Avg merge
23h
Merged PRs (30d)
7

Description

Discovered while analyzing eclipse-ee4j/mojarra#5969.

A resource name carrying a query string, as in ``, is forbidden by the resource identifier grammar, contradicted by the renderer algorithm, and simultaneously required by the TCK. All three cannot be right.

### What the specification says

Section 2.6.1.3 "Resource Identifiers" defines `[localePrefix/][libraryName/][libraryVersion/]resourceName[/resourceVersion]` and states that the valid characters for every segment, `resourceName` included, are XML NameChar excluding the path separator and `:`, with `resourceName` additionally allowed to contain the path separator. Neither `?` nor `=` is an XML NameChar. The same section requires that an identifier which does not follow these rules "must not be considered valid and must be ignored silently".

The Standard HTML RenderKit documentation, "Common Algorithm for Obtaining A Resource to Render", requires the resource renderers to look up the `name` attribute, look up the `library` attribute, and "create the resource by calling `Application.getResourceHandler.createResource(name, library)`" — that is, with the attribute value verbatim.

The only place the specification contemplates a query string at all is on the other end: the Script renderer's encode behavior (`changed_modified_2_1`, and the same clause on the Stylesheet renderer since `changed_modified_5_0`) says "Call `resource.getRequestPath()`. If the result contains a query string, take care to handle it correctly." That is about the `?ln=…&loc=…&con=…` which `getRequestPath()` itself produces, not about a query string in the name.

### What the TCK requires

`ee.jakarta.tck.faces.faces22.render_kit.Issue2172IT`, over fixture `issue2172.xhtml` containing ``, asserts that the rendered resource URL contains `ln=alibrary`, `v=1` and an escaped ampersand. An implementation that treats the name as an invalid resource identifier and ignores it silently, as 2.6.1.3 requires, fails this test.

`ee.jakarta.tck.faces.faces22.ajax_lifecycle.Issue4345IT` likewise drives `` and asserts the query string reaches the DOM unescaped. Its fixture carries the comment "h:outputStylesheet does not support params in the URL, so generate a similar link manually", with the stylesheet variant commented out — the TCK's own record that the behavior was never consistent.

### What implementations do

Both implementations support the extension, in implementation-specific places, and neither documents it in the VDL docs, where the `name` attribute of `h:outputScript`, `h:outputStylesheet` and `h:graphicImage` is described only as "The resourceName for this resource".

Mojarra splits the name at `?` in one place, `ScriptStyleBaseRenderer`, and re-appends the query to the request path. Every other consumer of the name sees it verbatim, which is what eclipse-ee4j/mojarra#5969 is about.

MyFaces splits at `?` in four places: `HtmlScriptRenderer`, `HtmlStylesheetRenderer`, `PartialViewContextImpl` and `FaceletsViewDeclarationLanguageUtils`.

Consequently `h:outputScript` and `h:outputStylesheet` accept a query string in the name on both implementations, while `h:graphicImage` and `#{resource['lib:name?v=1']}` do not, on either.

### Why users write this in the first place

The only versioning mechanism the specification offers is the `resourceVersion` segment, which requires a directory per resource with the version as the leaf file name (`resources/css/theme.css/1_0.css`). That cannot express a build-generated content hash without restructuring the output of every asset pipeline, so users reach for `?v=` instead. Whatever is decided below, a supported per-resource cache busting mechanism would remove the motivation for the extension entirely.

### Proposal

Decide one way and make all three artifacts agree.

Bless it: state in 2.6.1.3 that a `resourceName` may carry a trailing query string introduced by `?`, that the query string is not part of the resource identifier and is removed before the resource is resolved, that it is appended to the value returned by `Resource#getRequestPath()`, and that the resource name used as key for `ResourceHandler#markResourceRendered` and `#isResourceRendered` is the name without the query string. Amend "Common Algorithm for Obtaining A Resource to Render" accordingly, and state whether the extension applies to every tag taking a `name` attribute or only to the script and stylesheet renderers — today it is the latter, in both implementations, which is the more surprising of the two options.

Or drop it: remove `Issue2172IT` and the query string part of `Issue4345IT`, and let implementations return `RES_NOT_FOUND` for such a name as 2.6.1.3 already requires, but this will break existing apps which relied on impl-specific behavior.

🤖 Generated with Claude Opus 5

Contributor guide

Open the contributing guide

Research direction

Start by reviewing the Resource Identifiers section, the Common Algorithm for Obtaining A Resource to Render, and TCK tests Issue2172IT and Issue4345IT. Compare the named Mojarra and MyFaces renderer behavior, then determine the agreed direction. Done requires the specification, TCK coverage, and implementation behavior to consistently support or reject query strings.

Written by the indexing model from the issue text.

Assessment

Tech stack
java
Domain
backend-api-design, testing-qa
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Active
Clarity
Needs clarification
Newbie friendliness
28/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.