Can the index.xhtml be stored in an external JAR file? What would be its URL? - jsf

I'd like to have all the facelets and managed bean into one external jar, but if I put de index.xhtml there I don't konw how to reference it.
If the jar structure is:
IndexManagedBean.class
META-INF/
resources/
pages/
index.xhtml
What is its URL?

Assuming that the JAR is placed in webapp's /WEB-INF/lib folder and that you're using JSF 2.x and that webapp's context path is /contextpath, and the FacesServlet is mapped on an URL pattern of *.xhtml then you can reference it by the following URL:
http://example.com/contextpath/pages/index.xhtml
See also
Structure for multiple JSF projects with shared code

Related

Issue with h:form - Returning 404 when submitting through h:commandbutton

I am working on a JSF (2.2) application. I am seeing some weird behavior working with h:form and h:commandbutton.
Issue - I have following code in say searchRecord.xhtml -
<h:form>
<!-- Input fields -->
<h:commandbutton type="submit" value="Search" title="Search" action="#{bean.search}"/>
</h:form>
The issue I am facing is when I click on submit button, it shows 404-page not found with URL pointing to current page. It is not executing the specified bean action.
I tried to debug this. When the form is getting translated into HTML, the form is getting generated with method="post" action="/MyApplication/WEB-INF/searchRecord.xhtml" (which looks to be the correct behaviour). Still, on clicking the button, I am getting 404.
Can anyone please help me figuring out what is the issue? I wasted my weekend figuring this out but in vain.
EDIT -
IDE - Eclipse
JSF Version - Mojarra 2.2.8
Directory structure of my project is -
Project
- Java Resource
----src -> contains java files
- WebContent
---- META-INF
---- WEB-INF
------facelets -> contains *.xhtml files
------resources -> contains img, css and JS files in respective folders
------commonLayout.xhtml
- index.xhtml
I access my application using a launchHandler servlet which validates the request parameters and forward to searchRecord.xhtml.
I am able to see searchRecord.xhtml. but Now when I click , I am getting 404.
As a standard, we are required to use servlet and then forward accordingly.
I found solution for my problem. The issue here was the wrong directory structure (Somehow I missed the point that resources under /WEB-INF are not reachable by URL. Thanks to #BalusC for pointing this out!!!). Based on the answers on below post -
JSF files inside WEB-INF directory, how do I access them?
Which XHTML files do I need to put in /WEB-INF and which not?
I restructured my projects as follows -
My Application
|- Java Resource
|----src -> contains java files
|- WebContent
|---- META-INF
|---- Resources -> contains img, css and JS files in respective folders
|---- JSF
| |--Contains client .xhtml files
|---- WEB-INF
| |--template -> contains the master templates for my application
| |--web.xml
|---- index.xhtml
Now the navigation is happening as expected and all the pages are displayed.
I am also planning to use JSF 2.2 configuration parameter and put resources under WEB-INF.

OmniFaces CDNResourceHandler could not find resources when not included locally

I'm using OmniFaces CDNResourceHandler to point my resources to a CDN, instead of local files.
I added this line in my XHTML file: <h:outputStylesheet library="twitter-bootstrap" name="bootstrap.min.css" />
And my faces-config.xml have this line:
<context-param>
<param-name>org.omnifaces.CDN_RESOURCE_HANDLER_URLS</param-name>
<param-value>
twitter-bootstrap:bootstrap.min.css=https://somehost/twitter-bootstrap/3.3.7/bootstrap.min.css
</param-value>
</context-param>
And I'm getting this error when access the page:
Unable to find resource twitter-bootstrap, bootstrap.min.css
Note: When I access the file at https://somehost/twitter-bootstrap/bootstrap.min.css I can download the file properly.
I'm using Mojarra under Wildfly configured to Development stage.
The resource handler is properly configured at faces-config.xml file.
<application>
<resource-handler>org.omnifaces.resourcehandler.CDNResourceHandler</resource-handler>
</application>
I did some tests, and I notice that the error doesn't occurs if I create an empty file bootstrap.min.css under WEBAPP_FOLDER/resources/twitter-bootstrap. If I delete the file, the errors occurs again.
Even I use CDN, do I need to keep resources locally?
The CDNResourceHandler is primarily intented to move auto-included JSF resources to a CDN, such as jsf.js file from <f:ajax>, or primefaces.js and jquery.js from PrimeFaces, or to automatically switch to a CDN when installed in production.
You don't need it in your case with a permanent CDN resource. Just use plain <link>.
<link rel="stylesheet" src="https://somehost/twitter-bootstrap/bootstrap.min.css" />
This is also explicitly mentioned in the CDNResourceHandler documentation.
For non-JSF resources, you can just keep using plain HTML <script> and <link> elements referring the external URL
Update: as you're not the first one who wondered about this, I've as per issue 122 bypassed this technical restriction for OmniFaces 2.6. In other words, you do not necessarily need a local resource anymore.

ExternalContext#getResourceAsStream() returns null, where to place the resource file?

I'm trying to obtain a PNG file as InputStream in my managed bean as below:
ExternalContext externalContext = FacesContext.getCurrentInstance().getExternalContext();
InputStream input = externalContext.getResourceAsStream("/myFile.png");
// input is null.
However, the InputStream is always null. How is this caused and how can I solve it?
Apparently you placed the resource in physically the wrong location.
The ExternalContext#getResourceAsStream(), which delegates in case of servlet containers under the covers to ServletContext#getResoruceAsStream(), has its root in the web content of the WAR (the parent folder of /WEB-INF and /META-INF folders, thus the files therein are also available this way), and the /META-INF/resources folder of all JARs in /WEB-INF/lib. In case of a JSF web application it are usually XHTML, CSS, JavaScript and image files.
In other words, it returns web resources. It doesn't return a disk file system resource, for that you need new FileInputStream() instead. It also doesn't return a classpath resource, for that you need ClassLoader#getResourceAsStream() instead. The classpath has its root in a.o. /WEB-INF/classes, all JARs in /WEB-INF/lib, and some VM/server-configured folders depending on the runtime environment.
In an usual web content file structure, the resource file has to be placed exactly here in order to obtain it the desired way:
WebContent
|-- META-INF
|-- WEB-INF
| |-- faces-config.xml
| `-- web.xml
|-- myFile.png <-- Here.
:
getResourceAsStream() vs FileInputStream
Accessing properties file in a JSF application programmatically
Where to place and how to read configuration resource files in servlet based application?
How to get the root path of a web project in java EE

Deploying backing bean with composite component in separate jar

I have some difficulties deploying my web app on JBoss AS 6.1. My current Project is separated into the main web app (controller/managed beans & web frontend using JSF 2 facelets) and one jar with the composite components + backing beans. But when I try to access the page I got an error that the specified component type could not be instantiated.
Copying the backing bean into the main web app solves the problem, but this isn't what I want. So is there anything to pay attention to?
The backing bean looks like
#FacesComponent(value = "elementBase")
public class ElementBase extends UINamingContainer {
...
}
and the composite components interface
<composite:interface componentType="elementBase">
... some attributes
</composite:interface>
The structure of the jar is the following
-- META-INF
|-- resources
| |-- components
| |-- elementBase.xhtml
-- com
|-- example
| |-- ElementBase.class
I've also tried to add faces-config.xml within META-INF folder, with the component type, but the component type was still not found.
Through the BalusC's answer to the question JEE6> Packaging JSF facelets (xhtml) and ManagedBeans as JAR
As to the managed beans and other JSF classes like validators, converters, etc, just annotate them with #ManagedBean, #FacesValidator, #FacesConverter, etc and package them in the JAR the usual way. You only need to provide a JSF 2.0 compatible /META-INF/faces-config.xml file in the JAR.
<?xml version="1.0" encoding="UTF-8"?>
<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>
This way JSF will be triggered to scan the classes in the JAR for JSF specific annotations. Alternatively you can also just register them in the JAR's faces-config.xml the JSF 1.x way.
and Java EE6 Tutorial: Application Configuration Resource File
You can have more than one application configuration resource file for an application. The JavaServer Faces implementation finds the configuration file or files by looking for the following:
A resource named /META-INF/faces-config.xml in any of the JAR files in the web application’s /WEB-INF/lib/ directory and in parent class loaders. If a resource with this name exists, it is loaded as a configuration resource. This method is practical for a packaged library containing some components and renderers. In addition, any file with a name that ends in faces-config.xml is also considered a configuration resource and is loaded as such.
A context initialization parameter, javax.faces.application.CONFIG_FILES, in your web deployment descriptor file that specifies one or more (comma-delimited) paths to multiple configuration files for your web application. This method is most often used for enterprise-scale applications that delegate to separate groups the responsibility for maintaining the file for each portion of a big application.
A resource named faces-config.xml in the /WEB-INF/ directory of your application. Simple web applications make their configuration files available in this way.
.. I could fix my problem.
Step by step solution
Create backing bean
#FacesComponent(value = "elementBase")
public class ElementBase extends UINamingContainer {
...
}
and a composite components with the following interface
<composite:interface componentType="elementBase">
... some attributes, value holder, ..
</composite:interface>
provide a faces-config.xml within the deployed jar, to indicate that the jar contains annotated classes. The structure of the deployed jar should look like
-- META-INF
|-- resources
| |-- components
| |-- elementBase.xhtml
|-- faces-config.xml
-- com
|-- example
| |-- ElementBase.class
deploy the jar within the /WEB-INF/lib folder of the web application.
Research/Related links and topics
JEE6> Packaging JSF facelets (xhtml) and ManagedBeans as JAR
Java EE6 Tutorial: Application Configuration Resource File
JSF facelets template packaging
How to create a modular JSF 2.0 application?

How to get an image or js from a JAR in the server in JSF (For a custom component)

I have done a custom JSF component (it looks like a combobox (icefaces selectonemenu)) but it uses a couple of images (png) and a bit of javascript.
I jar everything, so then the developers use it as a jar copied in the web-inf/lib folder.
The image and the js are just for this custom component, so I can't make them put this image and js in his project, it has to be in MY jar.
I jar everything and it works almost great, just the image and the JS, I do not get them to work. I do not know how to reference them being in the jar. I could make them work as long as they are part of the application, but not being part of the jar.
How should I do to get them in my encodebegin code for example?
I am using JSF with icefaces 1.8
Thanks in advance!!
If you're already on JSF 2.0, it should work just fine out the box when you're using #ResourceDependency or #ResourceDependencies annotation which can resolve resources based on JAR's /META-INF/resources folder.
On JSF 1.x, your best bet is to create a custom "resource servlet" which is mapped on a certain URL pattern, e.g. /com.nahiko.resources/* and just streams the resources from the classpath to the HTTP response. Basic kickoff example:
String path = "/META-INF/resources" + request.getPathInfo();
InputStream input = getClass().getResourceAsStream(path);
OutputStream output = response.getOutputStream();
// ...
Document along your JAR that this servlet has to be mapped. Or if you target a Servlet 3.0 container, just add the #WebServlet annotation to get it to auto-register.

Resources