FacesConverter is null (JSF 2.3, CDI 2.0) - cdi

I tried to setup a FacesConverter to display some entity through my JSF page as referenced in JSF specification.
I'm running the following:
- Open Liberty 19.0.0.11 (tested on 19.0.0.6 as well, don't ask me why this version, I picked randomly another one)
- Java Open JDK 13
- JSF 2.3
- CDI 2.0
I've added to my project the following web.xml:
<web-app id="WebApp_ID" version="4.0" 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_4_0.xsd">
<display-name>TestConverterInjection</display-name>
<servlet>
<servlet-name>Faces Servlet</servlet-name>
<servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
<load-on-startup>1</load-on-startup>
<enabled>true</enabled>
<async-supported>false</async-supported>
</servlet>
<servlet-mapping>
<servlet-name>Faces Servlet</servlet-name>
<url-pattern>
*.xhtml</url-pattern>
</servlet-mapping>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index.htm</welcome-file>
<welcome-file>index.jsp</welcome-file>
<welcome-file>default.html</welcome-file>
<welcome-file>default.htm</welcome-file>
<welcome-file>default.jsp</welcome-file>
</welcome-file-list>
</web-app>
The following faces-config.xml:
<?xml version="1.0" encoding="UTF-8"?>
<faces-config
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-facesconfig_2_3.xsd"
version="2.3">
</faces-config>
The following beans.xml:
<?xml version="1.0" encoding="UTF-8"?>
<beans 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/beans_2_0.xsd"
bean-discovery-mode="all"
version="2.0">
</beans>
I do have an AppConfig class, annotated with #FacesConfig(Version.JSF_2_3). All fine so far.
I've simple TestConverter annotated as such:
#FacesConverter(value = "testConverter", managed = true)
When looking through the BeanManager, my TestConverter seems to be available as it appears in the list.
My test.xhtml file looks like this:
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:ui="http://java.sun.com/jsf/facelets">
<h:outputText value="#{testBean.selectedEntity.id}">
</h:outputText>
<br/>
<h:outputText value="#{testBean.selectedEntity}" converter="testConverter">
</h:outputText>
</html>
And my backing bean:
package com.test.beans;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import javax.annotation.PostConstruct;
import javax.enterprise.inject.Any;
import javax.enterprise.inject.spi.Bean;
import javax.enterprise.inject.spi.BeanManager;
import javax.enterprise.util.AnnotationLiteral;
import javax.faces.view.ViewScoped;
import javax.inject.Inject;
import javax.inject.Named;
import com.test.entities.MyEntity;
#Named("testBean")
#ViewScoped
public class TestBean implements Serializable {
private List<MyEntity> listEntities;
private MyEntity selectedEntity;
#Inject private BeanManager beanManager;
#PostConstruct
public void init() {
this.listEntities = new ArrayList<MyEntity>();
for(int i = 0; i < 5; i++) {
this.listEntities.add(new MyEntity(i, "test_"+i, i+"_test"));
}
this.selectedEntity = this.listEntities.get(0);
Set<Bean<?>> beans = beanManager.getBeans(Object.class,new AnnotationLiteral<Any>() {});
for (Bean<?> bean : beans) {
System.out.println("bean: "+bean.getBeanClass().getName());
}
}
public List<MyEntity> getListEntities() {
return listEntities;
}
public void setListEntities(List<MyEntity> listEntities) {
this.listEntities = listEntities;
}
public MyEntity getSelectedEntity() {
return selectedEntity;
}
public void setSelectedEntity(MyEntity selectedEntity) {
this.selectedEntity = selectedEntity;
}
}
Should be all good right ? Well, at least it worked with Apache TomEE 8.0.0 PluME. But here on Open Liberty, I'm getting:
SRVE0777E: Exception émise par la classe d'application 'javax.faces.webapp.FacesServlet.service:236'
javax.servlet.ServletException:
at javax.faces.webapp.FacesServlet.service(FacesServlet.java:236)
at com.ibm.ws.webcontainer.servlet.ServletWrapper.service(ServletWrapper.java:1255)
at [internal classes]
Caused by: java.lang.NullPointerException:
at org.apache.myfaces.cdi.converter.FacesConverterCDIWrapper.getAsString(FacesConverterCDIWrapper.java:62)
... 1 more
So, it looks like my bean is instantiated but is null... Features of Open Liberty are javaee8-0 (to be sure there wasn't anything missing). In the example above, if I'm removing the "managed = true" in my converter, it works. Some bug within CDI ?

I investigated the issue and I found that it's caused by beanManager.getBeans call. The bean is registered in the beanManger (as you demonstrated), but it's just not retrieved properly. Since the Converter uses generics, you need to search by type instead of class. I opened an issue in the MyFaces community and provided a patch! :)
https://issues.apache.org/jira/browse/MYFACES-4311
The fix will be included in MyFaces 2.3.7.
Thanks for spotting this one!

Related

Simple Jetty/JSF file upload won't submit

I've already looked at this one and the related tickets to no avail.
I have, what looks like the, simplest example possible
<h:form enctype="multipart/form-data" prependId="false">
<h:outputText value="File: "></h:outputText>
<h:inputFile value="#{configUploadController.uploadedFile}" />
<h:commandButton value="Save" type="submit" action="#{configUploadController.uploadFile}" style="color: red;"></h:commandButton>
</h:form>
I put a breakpoint in my uploadFile method but it never gits hit. when I remove the enctype from the form it does try to submit but then I get the obvious error...
javax.servlet.ServletException: Content-Type != multipart/form-data
And just for completeness, I remove the <h:inputFile> and enctype and can see my breakpoint being hit. When I set enctype to text/plain it DOESNT hit the breakpoint. However, when I set enctype to gibberish it DOES hit the breakpoint :(
Am I missing a dependency or config somewhere?
And in case it matters, my web.xml...
<?xml version="1.0" encoding="UTF-8"?>
<web-app 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"
version="3.1">
<!-- File(s) appended to a request for a URL that is not mapped to a web
component -->
<welcome-file-list>
<welcome-file>status.xhtml</welcome-file>
</welcome-file-list>
<context-param>
<param-name>com.sun.faces.expressionFactory</param-name>
<param-value>com.sun.el.ExpressionFactoryImpl</param-value>
</context-param>
<listener>
<description>Initializes Oracle JSF</description>
<listener-class>com.sun.faces.config.ConfigureListener</listener-class>
</listener>
<!-- Define the JSF servlet (manages the request processing life cycle for
JavaServer Faces) -->
<servlet>
<servlet-name>faces-servlet</servlet-name>
<servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
<load-on-startup>0</load-on-startup>
</servlet>
<!-- Map following files to the JSF servlet -->
<servlet-mapping>
<servlet-name>faces-servlet</servlet-name>
<url-pattern>*.xhtml</url-pattern>
</servlet-mapping>
</web-app>
jsf-api-2.2.15
jsf-impl-2.2.15
el-api-2.2
el-impl-2.2
jetty 9.4.18
javax.servlet-api-3.1.0
Instead of working around with a servlet (as per other answer) the actual problem was Jetty needs the multipart config setting up per multipart request.
Simple way to do this would be to add a filter that adds it as necessary, eg.
public class LoginFilter implements Filter {
private static final String MULTIPART_FORM_DATA = "multipart/form-data";
private static final MultipartConfigElement MULTI_PART_CONFIG =
new MultipartConfigElement(System.getProperty("java.io.tmpdir"));
#Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain)
throws IOException, ServletException {
HttpServletRequest httpServletRequest = (HttpServletRequest) request;
HttpServletResponse httpServletResponse = (HttpServletResponse) response;
String contentType = request.getContentType();
if (contentType != null && contentType.startsWith(MULTIPART_FORM_DATA))
request.setAttribute(Request.__MULTIPART_CONFIG_ELEMENT, MULTI_PART_CONFIG);
filterChain.doFilter(request, response);
}
}
See also:
How to implement FileUpload in embedded Jetty?
So, I haven't spent the time to track down why but jetty doesn't appear to like multipart forms. I got round it by using a servlet. Solution looks like this...
I've gone with ajax approach and a HTML form so I can specify my action, that matches the servlets pattern...
<form action="upload/config" enctype="multipart/form-data" method="post">
<h:inputFile id="file" />
<br />
<h:commandButton type="submit" value="Upload">
<f:ajax execute="file" render="#all"/>
</h:commandButton>
</form>
And the servlet...
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import javax.servlet.MultipartConfigElement;
import javax.servlet.annotation.MultipartConfig;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.Part;
import org.eclipse.jetty.server.Request;
#WebServlet("upload")
#MultipartConfig
public class UploadServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
#Override
protected void doPost(HttpServletRequest request, HttpServletResponse resp) {
try {
// This needed to get access to the parts
MultipartConfigElement multipartConfigElement = new MultipartConfigElement((String)null);
request.setAttribute(Request.__MULTIPART_CONFIG_ELEMENT, multipartConfigElement);
Part filePart = request.getPart("file");
try ( InputStream inputStream = filePart.getInputStream(); ) {
// Do what you want with your part
} catch (Exception e) {
resp.setStatus(500);
}
} catch (Exception e) {
resp.setStatus(500);
}
}
}

Creating a taglib.xml with a TagHandler makes annotated custom components fail to work

As an exercise, I'm creating some custom components in jsf 2.2 by using just annotations. For now I am not interested in a taglib for completion in the ui and since that exempts me from maintaining it, initial development is quicker. This al works perfectly. In this example I have one component that, for now, extends the PrimeFaces InputText (changing that does not make a difference), a clean faces-config (correctly 2.2 namespaced) and a simple page
component:
package my.custom.xforms;
import javax.faces.application.ResourceDependencies;
import javax.faces.application.ResourceDependency;
import javax.faces.component.FacesComponent;
import org.primefaces.component.inputtext.InputText;
#FacesComponent(value = "xforms.input", createTag = true,
namespace = "http://www.w3.org/2002/xforms", tagName = "input")
#ResourceDependencies({
#ResourceDependency(library="primefaces", name="primefaces.css"),
#ResourceDependency(library="primefaces", name="jquery/jquery.js"),
#ResourceDependency(library="primefaces", name="primefaces.js")}
)
public class Input extends InputText {
public Input() {
setRendererType("xforms.inputRenderer");
}
#Override
public String getFamily() {
return "my.xforms.components";
}
}
faces-config.xml
<faces-config 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-facesconfig_2_2.xsd"
version="2.2">
</faces-config>
page
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:xf="http://www.w3.org/2002/xforms"
xmlns:p="http://primefaces.org/ui">
<h:head/>
<h:body>
<xf:input />
</h:body>
</html>
This nicely shows a 'PrimeFaces' text input.
As an exercise, I added a tag that defines a model (internal to 'my' engine) that has no ui interaction. So my thought was to add a TagHandler (it does not need to manipulate the tags before it either, so maybe I should just extend UIComponentBase, but that is not the 'issue' now). TagHandlers cannot be created via annotations from what I can see, so I created a taglib.xml and put just my TagHandler in there.
taghandler
package my.custom.xforms;
import java.io.IOException;
import javax.el.ELException;
import javax.faces.FacesException;
import javax.faces.component.UIComponent;
import javax.faces.view.facelets.ComponentHandler;
import javax.faces.view.facelets.FaceletContext;
import javax.faces.view.facelets.FaceletException;
import javax.faces.view.facelets.TagConfig;
import javax.faces.view.facelets.TagHandler;
public class ModelTagHandler extends TagHandler {
public ModelTagHandler(TagConfig tagConfig) {
super(tagConfig);
}
public void apply(FaceletContext faceletContext, UIComponent parent) throws IOException, FacesException, FaceletException, ELException {
if (ComponentHandler.isNew(parent)) {
System.out.println("XForms Model encountered");
}
}
}
new page
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:xf="http://www.w3.org/2002/xforms"
xmlns:p="http://primefaces.org/ui">
<h:head/>
<h:body>
<xf:model /> <!-- can be put in h:head to, does not make a difference -->
<xf:input />
</h:body>
</html>
taglib
<facelet-taglib version="2.2"
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-facelettaglibrary_2_2.xsd">
<namespace>http://www.w3.org/2002/xforms</namespace>
<tag>
<tag-name>model</tag-name>
<handler-class>my.custom.xforms.ModelTagHandler</handler-class>
</tag>
</facelet-taglib>
To my surprise (well only partly), my custom component created with just annotations, stopped working with the following error.
/components/page.xhtml #12,33 <xf:input> Tag Library supports namespace: http://www.w3.org/2002/xforms, but no tag was defined for name: input
It only started working again if I put the custom component in my taglib to.
<tag>
<tag-name>input</tag-name>
<component>
<component-type>xforms.input</component-type>
<renderer-type>xforms.inputRenderer</renderer-type>
</component>
</tag>
Is this expected behaviour? Or should the taghandler be declared in a different way? I tried a lot of combinations of keywords in google, but to no avail. Not finding a bug, nor any hint to do things differently, nothing.
I'm currently running all this in
Wildfly 8.0.0-Final (Mojarra 2.2.5-jbossorg-3 20140128-1641)
java7
PrimeFaces 5.1
OmniFaces 2.0.
I will try to run it on a newer WildFly tomorrow or just try to update to the latest Mojarra (maybe in a clean Tomcat or whatever).

Unable to inject No-Interface EJB with security defined

I am trying to deploy an enterprise application EAR consisting of:
an EJB 3.1 module containing stateless session beans
a web module containing servlets
to Apache Geronimo V3.0 (packaged as a WebSphere Community 3.0.0.4 Server).
The beans are exposed through the #LocalBean annotation and injected into the servlets using the #EJB annotation.
Without any application security settings defined, everything works flawlessly. But, as soon as I define even the simplest security setup, injection fails with the message:
java.lang.IllegalArgumentException: Invalid method interface: LocalBean
javax.security.jacc.EJBMethodPermission$MethodSpec.checkMethodInterface(EJBMethodPermission.java:303)
javax.security.jacc.EJBMethodPermission$MethodSpec.(EJBMethodPermission.java:209)
javax.security.jacc.EJBMethodPermission.(EJBMethodPermission.java:90)
org.apache.geronimo.openejb.GeronimoSecurityService.isCallerAuthorized(GeronimoSecurityService.java:100)
org.apache.openejb.core.stateless.StatelessContainer.invoke(StatelessContainer.java:159)
org.apache.openejb.core.ivm.EjbObjectProxyHandler.synchronizedBusinessMethod(EjbObjectProxyHandler.java:255)
org.apache.openejb.core.ivm.EjbObjectProxyHandler.businessMethod(EjbObjectProxyHandler.java:235)
org.apache.openejb.core.ivm.EjbObjectProxyHandler._invoke(EjbObjectProxyHandler.java:92)
org.apache.openejb.core.ivm.BaseEjbProxyHandler.invoke(BaseEjbProxyHandler.java:284)
com.sun.proxy.$Proxy117.getSysTime(Unknown Source)
dk.danicon.servlet.Systime.doGet(Systime.java:43)
javax.servlet.http.HttpServlet.service(HttpServlet.java:575)
javax.servlet.http.HttpServlet.service(HttpServlet.java:668)
The security configuration works perfectly and prompts for credentials on servlets defined with an annotation like the one below, if they don't try to inject an EJB:
#ServletSecurity(#HttpConstraint(rolesAllowed={"admin"}))
I can make the injection work by removing the #LocalBean and implementing a #Local interface instead. But, from what I have been able to read on the subject, this should work with no-interface views as well - and I would like to avoid the added overhead from the interface.
I am attaching the relevant configuration files below and hope someone can tell me what I'm missing here?
application.xml (EAR module):
<?xml version="1.0" encoding="UTF-8"?>
<application id="Application_ID" version="6" 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/application_6.xsd">
<display-name>TestEar</display-name>
<module id="Module_1383740442312">
<web>
<web-uri>TestWeb.war</web-uri>
<context-root>test</context-root>
</web>
</module>
<module id="Module_1383741874882">
<ejb>TestEjb.jar</ejb>
</module>
</application>
geronimo-application.xml (EAR module):
<?xml version="1.0" encoding="UTF-8"?>
<app:application xmlns:app="http://geronimo.apache.org/xml/ns/j2ee/application-2.0" application-name="TestEar" xmlns:bp="http://www.osgi.org/xmlns/blueprint/v1.0.0" xmlns:client="http://geronimo.apache.org/xml/ns/j2ee/application-client-2.0" xmlns:conn="http://geronimo.apache.org/xml/ns/j2ee/connector-1.2" xmlns:dep="http://geronimo.apache.org/xml/ns/deployment-1.2" xmlns:ejb="http://openejb.apache.org/xml/ns/openejb-jar-2.2" xmlns:jaspi="http://geronimo.apache.org/xml/ns/geronimo-jaspi" xmlns:log="http://geronimo.apache.org/xml/ns/loginconfig-2.0" xmlns:name="http://geronimo.apache.org/xml/ns/naming-1.2" xmlns:pers="http://java.sun.com/xml/ns/persistence" xmlns:pkgen="http://openejb.apache.org/xml/ns/pkgen-2.1" xmlns:sec="http://geronimo.apache.org/xml/ns/security-2.0" xmlns:web="http://geronimo.apache.org/xml/ns/j2ee/web-2.0.1">
<dep:environment>
<dep:moduleId>
<dep:groupId>dk.danicon</dep:groupId>
<dep:artifactId>application</dep:artifactId>
<dep:version>1.0</dep:version>
<dep:type>car</dep:type>
</dep:moduleId>
<dep:dependencies>
<dep:dependency>
<dep:groupId>org.apache.geronimo.framework</dep:groupId>
<dep:artifactId>j2ee-security</dep:artifactId>
<dep:type>car</dep:type>
</dep:dependency>
<dep:dependency>
<dep:groupId>console.dbpool</dep:groupId>
<dep:artifactId>jdbc_ssodb</dep:artifactId>
<dep:version>1.0</dep:version>
<dep:type>car</dep:type>
</dep:dependency>
</dep:dependencies>
</dep:environment>
<sec:security>
<sec:role-mappings>
<sec:role role-name="admin">
<sec:principal class="org.apache.geronimo.security.realm.providers.GeronimoGroupPrincipal" name="ADMIN"/>
</sec:role>
</sec:role-mappings>
</sec:security>
<dep:gbean class="org.apache.geronimo.security.realm.GenericSecurityRealm" name="webrealm">
<dep:attribute name="realmName">webrealm</dep:attribute>
<dep:reference name="ServerInfo">
<dep:name>ServerInfo</dep:name>
</dep:reference>
<dep:xml-reference name="LoginModuleConfiguration">
<log:loginConfig>
<log:login-module control-flag="REQUIRED" wrap-principals="false">
<log:login-domain-name>webrealm</log:login-domain-name>
<log:login-module-class>org.apache.geronimo.security.realm.providers.SQLLoginModule</log:login-module-class>
<log:option name="dataSourceName">jdbc/ssodb</log:option>
<log:option name="userSelect">SELECT username, password FROM v4.app_users WHERE username = ?</log:option>
<log:option name="groupSelect">SELECT username, group_name FROM v4.app_users WHERE username = ?</log:option>
<log:option name="digest"/>
<log:option name="encoding"/>
</log:login-module>
</log:loginConfig>
</dep:xml-reference>
</dep:gbean>
</app:application>
ejb-jar.xml (EJB module):
<?xml version="1.0" encoding="UTF-8"?>
<ejb-jar version="3.1" 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/ejb-jar_3_1.xsd">
<display-name>TestEjb </display-name>
</ejb-jar>
openejb-jar.xml (EJB module):
<?xml version="1.0" encoding="UTF-8"?>
<ejb:openejb-jar xmlns:ejb="http://openejb.apache.org/xml/ns/openejb-jar-2.2" xmlns:app="http://geronimo.apache.org/xml/ns/j2ee/application-2.0" xmlns:bp="http://www.osgi.org/xmlns/blueprint/v1.0.0" xmlns:client="http://geronimo.apache.org/xml/ns/j2ee/application-client-2.0" xmlns:conn="http://geronimo.apache.org/xml/ns/j2ee/connector-1.2" xmlns:dep="http://geronimo.apache.org/xml/ns/deployment-1.2" xmlns:jaspi="http://geronimo.apache.org/xml/ns/geronimo-jaspi" xmlns:log="http://geronimo.apache.org/xml/ns/loginconfig-2.0" xmlns:name="http://geronimo.apache.org/xml/ns/naming-1.2" xmlns:pers="http://java.sun.com/xml/ns/persistence" xmlns:pkgen="http://openejb.apache.org/xml/ns/pkgen-2.1" xmlns:sec="http://geronimo.apache.org/xml/ns/security-2.0" xmlns:web="http://geronimo.apache.org/xml/ns/j2ee/web-2.0.1">
<dep:environment>
<dep:moduleId>
<dep:groupId>dk.danicon</dep:groupId>
<dep:artifactId>ejbmodule</dep:artifactId>
<dep:version>1.0</dep:version>
<dep:type>car</dep:type>
</dep:moduleId>
</dep:environment>
</ejb:openejb-jar>
web.xml (WEB module):
<?xml version="1.0" encoding="UTF-8"?>
<web-app id="WebApp_ID" version="3.0" 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-app_3_0.xsd">
<display-name>TestWeb</display-name>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
</welcome-file-list>
<login-config>
<auth-method>BASIC</auth-method>
<realm-name>webrealm</realm-name>
</login-config>
</web-app>
geronimo-web.xml (WEB module):
<?xml version="1.0" encoding="UTF-8"?>
<web:web-app xmlns:web="http://geronimo.apache.org/xml/ns/j2ee/web-2.0.1" xmlns:app="http://geronimo.apache.org/xml/ns/j2ee/application-2.0" xmlns:bp="http://www.osgi.org/xmlns/blueprint/v1.0.0" xmlns:client="http://geronimo.apache.org/xml/ns/j2ee/application-client-2.0" xmlns:conn="http://geronimo.apache.org/xml/ns/j2ee/connector-1.2" xmlns:dep="http://geronimo.apache.org/xml/ns/deployment-1.2" xmlns:ejb="http://openejb.apache.org/xml/ns/openejb-jar-2.2" xmlns:jaspi="http://geronimo.apache.org/xml/ns/geronimo-jaspi" xmlns:log="http://geronimo.apache.org/xml/ns/loginconfig-2.0" xmlns:name="http://geronimo.apache.org/xml/ns/naming-1.2" xmlns:pers="http://java.sun.com/xml/ns/persistence" xmlns:pkgen="http://openejb.apache.org/xml/ns/pkgen-2.1" xmlns:sec="http://geronimo.apache.org/xml/ns/security-2.0">
<dep:environment>
<dep:moduleId>
<dep:groupId>dk.danicon</dep:groupId>
<dep:artifactId>webmodule</dep:artifactId>
<dep:version>1.0</dep:version>
<dep:type>car</dep:type>
</dep:moduleId>
</dep:environment>
<web:context-root>/test</web:context-root>
<web:security-realm-name>webrealm</web:security-realm-name>
</web:web-app>
Sample EJB:
package dk.danicon.ejb;
import javax.annotation.security.RolesAllowed;
import javax.ejb.LocalBean;
import javax.ejb.Stateless;
#Stateless
#LocalBean
#RolesAllowed({"admin"})
public class SysTime {
public SysTime() {
}
public long getSysTime() {
return System.currentTimeMillis();
}
}
Sample servlet:
package dk.danicon.servlet;
import java.io.IOException;
import java.io.PrintWriter;
import javax.ejb.EJB;
import javax.servlet.ServletException;
import javax.servlet.annotation.HttpConstraint;
import javax.servlet.annotation.ServletSecurity;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import dk.danicon.ejb.SysTime;
#WebServlet("/testsystime")
#ServletSecurity(#HttpConstraint(rolesAllowed={"admin"}))
public class TestSystime extends HttpServlet {
private static final long serialVersionUID = 1L;
#EJB
SysTime systime;
public TestSystime() {
super();
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
PrintWriter pw = response.getWriter();
pw.println("<html><body><h3>Systime</h3>");
pw.println("<p>System time: " + systime.getSysTime() + " - " + systime.getClass().getName() + "</p>");
if(request.getUserPrincipal() != null)
pw.println("<p>Principal: " + request.getUserPrincipal().getName() + "</p>");
pw.println("</body></html>");
}
}
This appears to be an OpenEJB bug since there is no such LocalBean method interface type. That said, I am somewhat surprised that EJBMethodPermission is throwing an exception since the javadoc for that class says that implementations should be flexible enough to support unknown method interface types.

How to upload files without turning it to temporary file? (NetBeans JSF Primefaces)

Good day to all!
I've been making a simple web Application using Netbeans, JSF and Primefaces that can upload .csv, .jpeg/.jpg and .pdf files. I made 2 folders which was stored in drive C: (uploaded folder and tmp folder).
I assigned the "uploaded" folder to where the uploaded files are stored and the "tmp" for the .tmp of the uploaded files. I've been through many question threads and video tutorial which I followed correctly.
I also downloaded the commons fileupload and commons io and added it to the library. It is working fine, it displays that it is uploading and even saw the .tmp file on the folder i assigned it to.
But I cannot see the uploaded files on my "uploaded" folder.
So, my question is,
How can I upload these files into my "uploaded" folder.
Here are my codes:
index.xhtml
<?xml version='1.0' encoding='UTF-8' ?>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:p="http://primefaces.org/ui">
<h:head>
<title>Facelet Title</title>
</h:head>
<h:body>
<h:form enctype="multipart/form-data" >
<p:fileUpload fileUploadListener="#{FileUploadControl.fileUploadControl}"
mode="advanced"
update="messages"
auto="true"
sizeLimit="10000000"
allowTypes="/(\.|\/)(gif|jpe?g|csv|pdf)$/"
/>
<!-- -->
<p:growl id="messages" showDetail="true"/>
</h:form>
</h:body>
</html>
FileUploadControl.java
package controller;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.Serializable;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
import javax.faces.context.FacesContext;
import org.primefaces.model.UploadedFile;
#ManagedBean
#SessionScoped
public class FileUploadControl implements Serializable {
private String destination = "C:\\uploaded\\";
private UploadedFile file;
public UploadedFile getFile() {
return file;
}
public void setFile(UploadedFile file) {
this.file = file;
}
public FileUploadControl() {
}
public void TransferFile(String fileName, InputStream in) {
try {
OutputStream out = new FileOutputStream(new File(destination + fileName));
int reader = 0;
byte[] bytes = new byte[(int) getFile().getSize()];
while ((reader = in.read(bytes)) != -1) {
out.write(bytes, 0, reader);
}
in.close();
out.flush();
out.close();
} catch (IOException e) {
System.out.println(e.getMessage());
}
}
public void upload() {
String extValidate;
if (getFile() != null) {
String ext = getFile().getFileName();
if (ext != null) {
extValidate = ext.substring(ext.indexOf(".")+1);
} else {
extValidate = "null";
if (extValidate.equals("pdf")) {
try {
TransferFile(getFile().getFileName(), getFile().getInputstream());
} catch (IOException ex) {
Logger.getLogger(FileUploadControl.class.getName()).log(Level.SEVERE, null, ex);
FacesContext context = FacesContext.getCurrentInstance();
context.addMessage(null, new FacesMessage("Wrong", "Error Uploading file..."));
}
FacesContext context = FacesContext.getCurrentInstance();
context.addMessage(null, new FacesMessage("Succesful", getFile().getFileName() + "is uploaded."));
} else {
FacesContext context = FacesContext.getCurrentInstance();
context.addMessage(null, new FacesMessage("Wrong_ext", "only extension .pdf"));
}
}
} else {
FacesContext context = FacesContext.getCurrentInstance();
context.addMessage(null, new FacesMessage("Wrong", "Select File!"));
}
}
}
web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="3.0" 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-app_3_0.xsd">
<context-param>
<param-name>javax.faces.PROJECT_STAGE</param-name>
<param-value>Development</param-value>
</context-param>
<!--File upload commons -->
<filter>
<filter-name>PrimeFaces FileUpload Filter</filter-name>
<filter-class>org.primefaces.webapp.filter.FileUploadFilter</filter-class>
<init-param>
<param-name>thresholdSize</param-name>
<param-value>51200</param-value>
</init-param>
<init-param>
<param-name>uploadDirectory</param-name>
<param-value>C:\tmp</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>PrimeFaces FileUpload Filter</filter-name>
<servlet-name>Faces Servlet</servlet-name>
</filter-mapping>
<!--File upload commons -->
<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>/faces/*</url-pattern>
</servlet-mapping>
<session-config>
<session-timeout>
30
</session-timeout>
</session-config>
<welcome-file-list>
<welcome-file>faces/index.xhtml</welcome-file>
</welcome-file-list>
Thank you for your response and help. looking forward to it!
The main reason it's failing as at now is that you haven't bound the value attribute to your backing bean variable, so getFile() will always return null and upload will do nothing.
You're still probably not going to get any results because it appears that you're trying to combine two different modes of operation of the <p:fileUpload/> component.
Simple mode
You don't define a fileUploadListener
You define a value attribute on the component and bind to the UploadedFile type attribute in your backing bean (which you have)
Advanced mode
You don't define a value attribute
You define a fileUploadListener which is bound to a method in your backing bean (which you also have)

Custom Facelet component in JSF

Is it possible to create a custom JSF core Facelet component. Something like <custom:composition> of <ui:composition>, or <custom:include> for <ui:include>
It would be helpful if someone can tell me the steps involved.
Thanks in advance,
Kaushal
It are in essence taghandlers. I.e. classes extending from TagHandler.
Here's a Hello World taghandler.
com.example.HelloTagHandler
public class HelloTagHandler extends TagHandler {
public HelloTagHandler(TagConfig config) {
super(config);
}
#Override
public void apply(FaceletContext context, UIComponent parent) throws IOException {
// Do your job here. This example dynamically adds another component to the parent.
if (ComponentHandler.isNew(parent)) {
UIOutput child = new HtmlOutputText();
child.setValue("Hello World");
parent.getChildren().add(child);
}
nextHandler.apply(context, parent); // Delegate job further to first next tag in tree hierarchy.
}
}
/WEB-INF/my.taglib.xml
<?xml version="1.0" encoding="UTF-8"?>
<facelet-taglib
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-facelettaglibrary_2_0.xsd"
version="2.0"
>
<namespace>http://example.com/my</namespace>
<tag>
<tag-name>hello</tag-name>
<handler-class>com.example.HelloTagHandler</handler-class>
</tag>
</facelet-taglib>
/WEB-INF/web.xml (note: this part is not mandatory when my.taglib.xml is in /META-INF folder of a JAR file inside /WEB-INF/lib like as with JSF component libraries):
<context-param>
<param-name>javax.faces.FACELETS_LIBRARIES</param-name>
<param-value>/WEB-INF/my.taglib.xml</param-value>
</context-param>
Usage in /some.xhtml
<html ... xmlns:my="http://example.com/my">
...
<my:hello />
To see the source code of Mojarra implementation of <ui:composition> and <ui:include>, click the links.
See also:
When to use <ui:include>, tag files, composite components and/or custom components?

Resources