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

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.

Related

How to use FullAjaxExceptionHandler with Spring Boot error page declarations?

How can we do when use onmifaces in the case of spring boot apps?, where the error pages declaration is made at EmbeddedServletContainerCustomizer class?
#Override
public void customize(ConfigurableEmbeddedServletContainer container) {
MimeMappings mappings = new MimeMappings(MimeMappings.DEFAULT);
mappings.add("eot", "application/vnd.ms-fontobject");
mappings.add("ttf", "application/x-font-ttf");
mappings.add("woff", "application/x-font-woff");
mappings.add("woff2", "application/x-font-woff2");
container.setMimeMappings(mappings);
container.addErrorPages(new ErrorPage(HttpStatus.NOT_FOUND, "/error.xhtml"));
container.addErrorPages(new ErrorPage(FaceletException.class, "/error.xhtml"));
container.addErrorPages(new ErrorPage(Throwable.class, "/error.xhtml"));
}
I have analized findErrorPageLocation and it uses WebXml that parses web.xml files.
The Servlet API in its current version does not support programmatically defining and obtaining error pages. That's why OmniFaces had to manually parse web.xml.
OmniFaces does not and will not support Spring specific APIs. I recommend to just keep using web.xml for error page configuration so that non-Spring libraries will be able to share them.

PrimeFaces 6 FileUploadFilter configuration with Spring Boot embedded Jetty

org.primefaces.webapp.filter.FileUploadFilter does not registered to my application, unless I define FileUploadFilter explicitly in my spring configuration like;
#Bean
FileUploadFilter fileUploadFilter() {
return new FileUploadFilter();
}
Referring to this question;
If you're however not using JSF 2.2 yet and you can't upgrade it
(should be effortless when already on a Servlet 3.0 compatible
container), then you need to manually register the below PrimeFaces
file upload filter in web.xml (it will parse the multi part request
and fill the regular request parameter map so that FacesServlet can
continue working as usual)
Conversely I have javax.faces in my classpath: org.glassfish:javax.faces:jar:2.2.13:compile. (and mojarra impl)
Should we go manually with this? Or else It can not be detected and registered automatically, we have to register a manual configuration to joinfaces
UPDATE: Actually this is not directly relevant to registration of FileUploadFilter. Embedded jetty in spring-boot does not pick up annotated configurations example of which FacesServlet has a #MultipartConfig annotation. I have opened an issue to spring-boot for that:
https://github.com/spring-projects/spring-boot/issues/6681
https://github.com/spring-projects/spring-boot/issues/6680 will fix the issue. WebServletHandler will pick up #MultipartConfig annotated classes.

spring-boot + JSF. Views *.jsf working properly but *.xhtml not

I'm using spring boot with jsf (primefaces). here you can find sample of my application. When I invoke this application using mvn spring-boot:run and access application with jsf or with xhtml everything works ok. But when I deploy this application to tomcat, xhtml page is not rendered properly. I can see page source (xhtml source, not html), but this is not wanted. I want to be able to display the same with .jsf and .xhtml.
Can anybody tell me what am I missing?
Edit:
as I reviewd this issue and it was not helpfull (I also have *.xhtml mapping for faces servlet and as I wrote before, this is working on spring-boot embedded tomcat but not on classic tomcat), I think the problem will be more related to the spring configuration, but I'm not sure what and where to change.
Thanks
Problem in spring config. Add this to file Application.java:
#Bean
public ViewResolver getViewResolver() {
InternalResourceViewResolver resolver = new InternalResourceViewResolver();
resolver.setPrefix("/view/");
resolver.setSuffix(".xhtml");
return resolver;
}

java.lang.IllegalArgumentException: Multiple entries with same key: interface javax.validation.constraints.Min

I'm running an EAR with EJB + EJB + WAR deployment in JBoss WildFly 8.2.0.Final with JSF 2.2 and RichFaces 4.5.2.Final. My problem is, that all RichFaces resources fail to load properly in the client. The generated URL don't resolve and return with HTTP 404.
The deployment is build upon Maven und results in the following structure:
The reason for using <scope>compile</scope> in the EJB module and not the WAR is that I need to extend RichFaces classes from within my EJB module. We've build a dynamic form generator based on some of the components.
As soon as I add JARs to EAR/lib/ and WAR/WEB-INF/lib/ by using <scope>compile</scope> instead of <scope>provided</scope> in the WAR module I get the following stacktrace while starting the application server:
Caused by: java.lang.IllegalArgumentException: Multiple entries with same key: interface javax.validation.constraints.Min=org.richfaces.javascript.LibraryFunctionImplementation#c77af4e and interface javax.validation.constraints.Min=org.richfaces.javascript.LibraryFunctionImplementation#5a903150
at com.google.common.collect.ImmutableMap.checkNoConflict(ImmutableMap.java:150)
at com.google.common.collect.RegularImmutableMap.checkNoConflictInBucket(RegularImmutableMap.java:104)
at com.google.common.collect.RegularImmutableMap.<init>(RegularImmutableMap.java:70)
at com.google.common.collect.ImmutableMap$Builder.build(ImmutableMap.java:254)
at org.richfaces.javascript.ClientServiceConfigParser.parseConfig(ClientServiceConfigParser.java:75)
at org.richfaces.application.ValidatorModule.createClientScriptService(ValidatorModule.java:65)
at org.richfaces.application.ValidatorModule.configure(ValidatorModule.java:60)
at org.richfaces.application.ServicesFactoryImpl.init(ServicesFactoryImpl.java:60)
at org.richfaces.application.InitializationListener.createFactory(InitializationListener.java:110)
at org.richfaces.application.InitializationListener.onStart(InitializationListener.java:69)
at org.richfaces.application.InitializationListener.processEvent(InitializationListener.java:167)
at javax.faces.event.SystemEvent.processListener(SystemEvent.java:108)
at com.sun.faces.application.ApplicationImpl.processListeners(ApplicationImpl.java:2190)
at com.sun.faces.application.ApplicationImpl.invokeListenersFor(ApplicationImpl.java:2163)
at com.sun.faces.application.ApplicationImpl.publishEvent(ApplicationImpl.java:303)
at org.jboss.as.jsf.injection.weld.ForwardingApplication.publishEvent(ForwardingApplication.java:294)
at com.sun.faces.config.ConfigManager.publishPostConfigEvent(ConfigManager.java:692)
at com.sun.faces.config.ConfigureListener.contextInitialized(ConfigureListener.java:260)
... 9 more
How can I solve this problem?
Frontend artifacts don't belong in EAR's /lib. They belong in WAR's /WEB-INF/lib. It would otherwise make the backend (the EJB) totally unreusable on other frontends (other WARs), such as Spring MVC, JAX-RS RESTful, "Plain vanilla" JSP/Servlet, etc..etc.. Using/importing JSF FacesContext and friends such as Servlet's HttpServletRequest in an EJB class is already a seriously big red alert. You should not be doing that.
Move that code to WAR. Or, if you intend to make it reusable across various WARs, make it a web fragment project instead which can then end up as another JAR in /WEB-INF/lib.
See also:
JSF Service Layer

init() method calls on every request

I am using JSF 2.0 and Liferay 6.1
On any kind of request to any Java class my init() is getting called. Even in case of PrimeFaces component calls for its related PrimeFaces Java method. This method should be called only once when my portlet will initialize.
#ManagedBean
#ViewScoped
public class MyMangedBean {
public void init() {
System.out.println("Init method called");
}
}
Please help me to find out possible solution.
EDIT
I found the component behind this cause
In my xhtml file I have
<bridge:inputFile id="MyFileUpload" size="50"
binding="#{myBean.toBeUploadFile}" onchange="{fileSelected(this);}" style="position: absolute;height: 29px;width:107px;opacity:0;filter: alpha(opacity=0);z-index:100;"/>
Whenever I remove its binding attribute. My project works fine. It will not call init() multiple times. But I need this attribute to get my file uploaded.
I have kept xml namespace as
xmlns:bridge="http://portletfaces.org/bridge"
I have also kept dependency for commons-io(version 1.3) and commons-filedownload(1.2.1) in pom.xml
I dont know what else I am missing for this component or what is actual cause behind this.
You should consider using the bridge:inputFile tag that comes with the latest release of Liferay Faces instead of the older obsolete tags that come from portletfaces.org.
There is a nice demo here that uses the bridge:inputFile that you can try on a Liferay tomcat portal instance, and then follow the same pattern that it uses for file upload.
That demo has been tested, it works great, and it is supported by Liferay.
There are many more demos that are tested and working well on Liferay Portal 6.1. You can download the source for them and build them for yourself as shown here. And follow the version scheme here to make sure that you align the correct versions of the Portal, Mojarra, and the Liferay Faces Bridge.
Hope that helps.

Resources