I have a Javaee7, JSF2 web app running in Glassfish 4.0 using maven.
I have all of my resources in my /src/main/webapp/resources
folder, but because I am using a framework, they are sometime nested in multiple subfolders, (i.e. resources/theme/plugin/bootstrap/script.js
).
The CSS, JS and image files that are stored one directory below the resources folder (i.e. resources/theme/custom.css
) would load fine with this code:
<h:outputScript library="theme" name="custom.js" />
But if I try to load a resource that's located in sub-folders, it doesn't work:
<h:outputScript library="theme" name="plugin/bootstrap/script.js" />
I've also tried this:
<h:outputScript name="theme/plugin/bootstrap/script.js" />
and
<h:outputScript name="plugin/bootstrap/script.js" />
But everything returns "Unable to load resource".
Here is the start of my web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="3.1" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd">
<context-param>
<param-name>javax.faces.PROJECT_STAGE</param-name>
<param-value>Development</param-value>
</context-param>
<context-param>
<param-name>javax.faces.WEBAPP_RESOURCES_DIRECTORY</param-name>
<param-value>/resources</param-value>
</context-param>
<context-param>
<param-name>javax.faces.FACELETS_SKIP_COMMENTS</param-name>
<param-value>true</param-value>
</context-param>
<!-- sets the default time zone for the web app -->
<context-param>
<param-name>javax.faces.DATETIMECONVERTER_DEFAULT_TIMEZONE_IS_SYSTEM_TIMEZONE</param-name>
<param-value>true</param-value>
</context-param>
<servlet>
<servlet-name>Faces Servlet</servlet-name>
<servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>Faces Servlet</servlet-name>
<url-pattern>*.xhtml</url-pattern>
</servlet-mapping>
And here is the pom.xml if that helps
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.WebStore</groupId>
<artifactId>MyApp</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>war</packaging>
<name>MyApp</name>
<properties>
<endorsed.dir>${project.build.directory}/endorsed</endorsed.dir>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>javax.mail</groupId>
<artifactId>mail</artifactId>
<version>1.4.3</version>
</dependency>
<dependency>
<groupId>net.coobird</groupId>
<artifactId>thumbnailator</artifactId>
<version>[0.4, 0.5)</version>
</dependency>
<dependency>
<groupId>org.omnifaces</groupId>
<artifactId>omnifaces</artifactId>
<version>1.7</version>
</dependency>
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.2.1</version>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>1.4</version>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>16.0.1</version>
</dependency>
<dependency>
<groupId>org.eclipse.persistence</groupId>
<artifactId>eclipselink</artifactId>
<version>2.5.1</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.eclipse.persistence</groupId>
<artifactId>org.eclipse.persistence.jpa.modelgen.processor</artifactId>
<version>2.5.1</version>
<scope>provided</scope>
</dependency>
<!--<dependency>
<groupId>org.glassfish.main.extras</groupId>
<artifactId>glassfish-embedded-all</artifactId>
<version>4.0</version>
</dependency>-->
<dependency>
<groupId>org.apache.derby</groupId>
<artifactId>derby</artifactId>
<version>10.10.1.1</version>
</dependency>
<dependency>
<groupId>javax</groupId>
<artifactId>javaee-web-api</artifactId>
<version>7.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.primefaces.extensions</groupId>
<artifactId>primefaces-extensions</artifactId>
<version>1.2.1</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
</dependency>
<dependency>
<groupId>com.paypal.sdk</groupId>
<artifactId>rest-api-sdk</artifactId>
<version>0.5.2</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.1</version>
<configuration>
<source>1.7</source>
<target>1.7</target>
<compilerArguments>
<endorseddirs>${endorsed.dir}</endorseddirs>
</compilerArguments>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.12.4</version>
<configuration>
<skipTests>true</skipTests>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>2.3</version>
<configuration>
<failOnMissingWebXml>false</failOnMissingWebXml>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>2.6</version>
<executions>
<execution>
<phase>validate</phase>
<goals>
<goal>copy</goal>
</goals>
<configuration>
<outputDirectory>${endorsed.dir}</outputDirectory>
<silent>true</silent>
<artifactItems>
<artifactItem>
<groupId>javax</groupId>
<artifactId>javaee-endorsed-api</artifactId>
<version>7.0</version>
<type>jar</type>
</artifactItem>
</artifactItems>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
I checked to see if there are security constraints that may prevent the access to the resources, but all of them pertain to a certain folder of xhtml files, so I doubt that is the issue. For example, most of my security constraints are /admin/*
or /user/*
etc.
Any help would be appreciated! thanks!
You'll either need to conform to JSF's resource library naming structure or abandon the nested directory structure you have altogether
JSF's somewhat complicated resource library naming convention is messing with you. Consider the following template as what constitutes a valid resource component path, per the JSF specification:
resources/<resourceIdentifier>
Where <resourceIdentifier>
is bound by the following structure:
[localePrefix/][libraryName/][libraryVersion/]resourceName[/resourceVersion]
Here are the rules:
If libraryVersion is present, it must be preceded by libraryName
If libraryVersion is present, any leaf files under libraryName must be ignored.
If resourceVersion is present, it must be preceded by resourceName
There must be a
/
between adjacent segments in aIf libraryVersion or resourceVersion are present, both must be a
_
separated list of integers, neither starting nor ending with_
If resourceVersion is present, it must be a version number in the same format as libraryVersion. An optional “file extension” may be used with the resourceVersion. If “file extension” is used, a “.” character, followed by a “file extension” must be appended to the version number.
As an example, resources/basic/2_3/script.js/1_3_4.js
fulfils the requirements for a valid resource path
According to the rules above:
<resources>/theme/custom.css
is fine and evaluates properly:[libraryName]/resourceName
<resources>/theme/plugin/bootstrap/script.js
will fail because it's evaluated as:[libraryName/][libraryVersion/]resourceName[/resourceVersion]
. According to the rules, several bits of that path fail the criteria for successful evaluation of the resource path
I just had a similar problem, because I wanted to keep jquery scripts in a separate folder.
I got it working by just adding the sub-folder to the library name:
<h:outputScript library="script/jquery" name="jquery.js"/>
but I don't know how reliable this is.
来源:https://stackoverflow.com/questions/24472095/jsf-is-unable-to-find-resources-in-sub-folders