"Contracts" path in windows is not detected
Hi,
Summary:
"contracts" folder in class path "/META-INF/contracts" is not being detected.
Environment:
- JSF Version: 4.0.12
- OS: Window 11
- IDE: Eclipse 9/2025
- JDK: jdk-17.0.12 & jdk-21
Folder structure:
META-INF --contracts ----default --------jakarta.faces.contract.xml --------page.xhtml
Issue Details:
After looking at the implementation source code, I found a bug in com.sun.faces.config.WebConfiguration where there is a hard-coded forward slash (UNIX style file separator) at line 93, which causes a condition mismatch in class com.sun.faces.facelets.util.Classpath at line 117 , since windows is using back slash (windows -style), below are the exact code snippets.
WebConfiguration (Line 93)
private static final String RESOURCE_CONTRACT_SUFFIX = "/" + ResourceHandler.RESOURCE_CONTRACT_XML;
WebConfiguration (Line 416)
try {
URL[] candidateURLs = Classpath.search(Util.getCurrentLoader(this), META_INF_CONTRACTS_DIR, RESOURCE_CONTRACT_SUFFIX,
Classpath.SearchAdvice.AllMatches);
for (URL curURL : candidateURLs) {
String cur = curURL.toExternalForm();
int i = cur.indexOf(META_INF_CONTRACTS_DIR) + META_INF_CONTRACTS_DIR_LEN + 1;
int j = cur.indexOf(RESOURCE_CONTRACT_SUFFIX);
if (i < j) {
foundContracts.add(cur.substring(i, j));
}
}
com.sun.faces.facelets.util.Classpath (Line 117)
for (int i = 0; i < fc.length; i++) {
path = fc[i].getAbsolutePath();
if (fc[i].isDirectory()) {
searchDir(result, fc[i], suffix);
} else if (path.endsWith(suffix)) { //here is the problem
// result.add(new URL("file:/" + path));
result.add(fc[i].toURL());
}
}
Proposed Solutions:
[Option 1] Use file.seprator property instead of the hardcoded value. [Option 2] Remove the RESOURCE_CONTRACT_SUFFIX constant , and update the code at WebConfigurator to be:
URL[] candidateURLs = Classpath.search(Util.getCurrentLoader(this), META_INF_CONTRACTS_DIR, ResourceHandler.RESOURCE_CONTRACT_XML,
Classpath.SearchAdvice.AllMatches);
for (URL curURL : candidateURLs) {
String cur = curURL.toExternalForm();
int i = cur.indexOf(META_INF_CONTRACTS_DIR) + META_INF_CONTRACTS_DIR_LEN + 1;
int j = cur.indexOf(ResourceHandler.RESOURCE_CONTRACT_XML)-1;
if (i < j) {
foundContracts.add(cur.substring(i, j));
}
}
[Option 3] Modify ClassPath class to alway replace the backward slashes at line 114, maybe with something like this.
path = fc[i].getAbsolutePath().replaceAll("\\\\", "/");
Thanks By the way, please keep up the great work.
Jalal