ICEfaces / Seam File Upload Component Does Not Download Files

Update

I'm currently on the ICEfaces forums to solve my problem - unfortunately, none of the options provided led to a solution now, but they really gave me a deeper understanding of the whole JSF topic (loans go to BalusC for that, how often: - )).

I will try to update this thread and post an answer if the problem is finally resolved, to help others who might run into it.

My results so far:

  • Disabling the multicast seam filter is required because it prevents the fileEntry component from working properly.
  • I still have nasty problems with the library in my application, which leads to (quiet) ClassLoading problems: there are 2 icefaces-ace.jar files, one in EAR / lib and one in EAR / WAR / WEB-INF / lib , Removing one of the WEB-INF causes the component to do nothing, removing one of the EAR / lib causes my application to no longer be deployed.

When moving all the interface cans (icefaces.jar, icefaces-ace.jar, icefaces-compat.jar) from EAR / lib to WEB-INF / lib, I get different ClassNotFoundExceptions for the jar part of my EAR: ValueChangeEvent, RowSelectorEvent, etc. .d. Could not be found (this means that all those events that come from the view to the backend). Example:

12:12:42,145 ERROR [org.jboss.msc.service.fail] (MSC service thread 1-16) MSC00001: Failed to start service jboss.deployment.subunit."myApp.ear"."myApp.jar".POST_MODULE: org.jboss.msc.service.StartException in service jboss.deployment.subunit."myApp.ear"."myApp.jar".POST_MODULE: Failed to process phase POST_MODULE of subdeployment "myApp.jar" of deployment "myApp.ear" at org.jboss.as.server.deployment.DeploymentUnitPhaseService.start(DeploymentUnitPhaseService.java:119) [jboss-as-server-7.1.1.Final.jar:7.1.1.Final] at org.jboss.msc.service.ServiceControllerImpl$StartTask.startService(ServiceControllerImpl.java:1811) [jboss-msc-1.0.2.GA.jar:1.0.2.GA] at org.jboss.msc.service.ServiceControllerImpl$StartTask.run(ServiceControllerImpl.java:1746) [jboss-msc-1.0.2.GA.jar:1.0.2.GA] at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1110) [rt.jar:1.7.0_06] at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603) [rt.jar:1.7.0_06] at java.lang.Thread.run(Thread.java:722) [rt.jar:1.7.0_06] Caused by: java.lang.RuntimeException: Error getting reflective information for class my.company.myApp.myExampleBean with ClassLoader ModuleClassLoader for Module "deployment.myApp.ear.myApp.jar:main" from Service Module Loader at org.jboss.as.server.deployment.reflect.DeploymentReflectionIndex.getClassIndex(DeploymentReflectionIndex.java:70) [jboss-as-server-7.1.1.Final.jar:7.1.1.Final] at org.jboss.as.ee.metadata.MethodAnnotationAggregator.runtimeAnnotationInformation(MethodAnnotationAggregator.java:58) at org.jboss.as.ee.component.deployers.InterceptorAnnotationProcessor.handleAnnotations(InterceptorAnnotationProcessor.java:85) at org.jboss.as.ee.component.deployers.InterceptorAnnotationProcessor.processComponentConfig(InterceptorAnnotationProcessor.java:70) at org.jboss.as.ee.component.deployers.InterceptorAnnotationProcessor.deploy(InterceptorAnnotationProcessor.java:55) at org.jboss.as.server.deployment.DeploymentUnitPhaseService.start(DeploymentUnitPhaseService.java:113) [jboss-as-server-7.1.1.Final.jar:7.1.1.Final] ... 5 more Caused by: java.lang.NoClassDefFoundError: com/icesoft/faces/component/ext/RowSelectorEvent at java.lang.Class.getDeclaredMethods0(Native Method) [rt.jar:1.7.0_06] at java.lang.Class.privateGetDeclaredMethods(Class.java:2442) [rt.jar:1.7.0_06] at java.lang.Class.getDeclaredMethods(Class.java:1808) [rt.jar:1.7.0_06] at org.jboss.as.server.deployment.reflect.ClassReflectionIndex.<init>(ClassReflectionIndex.java:65) [jboss-as-server-7.1.1.Final.jar:7.1.1.Final] at org.jboss.as.server.deployment.reflect.DeploymentReflectionIndex.getClassIndex(DeploymentReflectionIndex.java:66) [jboss-as-server-7.1.1.Final.jar:7.1.1.Final] ... 10 more Caused by: java.lang.ClassNotFoundException: com.icesoft.faces.component.ext.RowSelectorEvent from [Module "deployment.myApp.ear.myApp.jar:main" from Service Module Loader] at org.jboss.modules.ModuleClassLoader.findClass(ModuleClassLoader.java:190) [jboss-modules.jar:1.1.1.GA] at org.jboss.modules.ConcurrentClassLoader.performLoadClassUnchecked(ConcurrentClassLoader.java:468) [jboss-modules.jar:1.1.1.GA] at org.jboss.modules.ConcurrentClassLoader.performLoadClassChecked(ConcurrentClassLoader.java:456) [jboss-modules.jar:1.1.1.GA] at org.jboss.modules.ConcurrentClassLoader.performLoadClass(ConcurrentClassLoader.java:398) [jboss-modules.jar:1.1.1.GA] at org.jboss.modules.ConcurrentClassLoader.loadClass(ConcurrentClassLoader.java:120) [jboss-modules.jar:1.1.1.GA] ... 15 more 

Whole story

I am working on a web application using Seam 2.3 and ICEfaces 3.1.0. This means that JSF2 is being used.

My application is deployed to JBoss AS 7.1.0 as an EAR containing a JAR for application logic and a WAR for all viewing-related materials.

I recently migrated from Seam 2.1.2 to Seam 2.3 and ICEfaces from 1.8.2 to 3.1.0. This step was terrible, but now everything is working fine, leaving aside some minor issues.

The only big problem is that when I use components to upload files, whether I use Seam components or ICEfaces components, the loaded file is always null in Seam and in ICEfaces, my FileEntryListener method will never be called.

With ICEfaces:

In versions of ICEfaces prior to 2.X, there was ice:inputFile component that was removed from 2.X and replaced with ace:fileEntry .

InputFile works well, but FileEntry does not. My problem is exactly the same as described in JSF: problems downloading files using the Icefaces component - the EntryListener file is never called. I tried the suggestions there (using enctype = "multipart / form-data" in the surrounding format, using h:commandButton to submit the form), but that didn't work. The only solution was to switch to Richfaces, for me this is not an option.

Using a seam:

Gladly, Seam has its own built-in component fileUpload, s:fileUpload .

It doesn’t work either, but at least it showed me the place to look further. When debugging the doDecode methods of this component, I found that my request is not a MultipartRequest. Crazy thing! All forms used to upload files declare enctype as multipart / form-data. I think the same thing happens when I try to use the ICEfaces component - there is no multi-page request, and this does not cause listeners to be called.

So: How do I get this to work? What is the point that the request does not arrive as MultipartRequest? Am I missing something in web / components.xml?

web.xml:

 <web-app 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/xmlns/ javaee/web-app_3_0.xsd" version="3.0"> <listener> <listener-class>org.jboss.seam.servlet.SeamListener</listener-class> </listener> <filter> <filter-name>Seam Filter</filter-name> <filter-class>org.jboss.seam.servlet.SeamFilter</filter-class> </filter> <filter-mapping> <filter-name>Seam Filter</filter-name> <url-pattern>*.seam</url-pattern> </filter-mapping> <servlet> <servlet-name>Faces Servlet</servlet-name> <servlet-class>javax.faces.webapp.FacesServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>Faces Servlet</servlet-name> <url-pattern>*.jsf</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>Faces Servlet</servlet-name> <url-pattern>/icefaces/*</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>Faces Servlet</servlet-name> <url-pattern>*.seam</url-pattern> </servlet-mapping> <servlet> <servlet-name>Seam Resource Servlet</servlet-name> <servlet-class>org.jboss.seam.servlet.SeamResourceServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>Seam Resource Servlet</servlet-name> <url-pattern>/seam/resource/*</url-pattern> </servlet-mapping> <servlet> <servlet-name>Resource Servlet</servlet-name> <servlet-class>com.icesoft.faces.webapp.CompatResourceServlet</servlet-class> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>Resource Servlet</servlet-name> <url-pattern>/xmlhttp/*</url-pattern> </servlet-mapping> <session-config> <session-timeout>60</session-timeout> </session-config> <context-param> <param-name>javax.faces.FACELETS_SKIP_COMMENTS</param-name> <param-value>true</param-value> </context-param> <context-param> <param-name>facelets.DEVELOPMENT</param-name> <param-value>true</param-value> </context-param> <context-param> <param-name>com.icesoft.faces.actionURLSuffix</param-name> <param-value>.seam</param-value> </context-param> <context-param> <param-name>javax.faces.FACELETS_REFRESH_PERIOD</param-name> <param-value>-1</param-value> </context-param> <context-param> <param-name>com.icesoft.faces.synchronousUpdate</param-name> <param-value>false</param-value> </context-param> <context-param> <param-name>com.icesoft.faces.doJSFStateManagement</param-name> <param-value>true</param-value> </context-param> <context-param> <param-name>com.icesoft.faces.standardRequestScope</param-name> <param-value>true</param-value> </context-param> <context-param> <param-name>com.icesoft.faces.uploadDirectory</param-name> <param-value>upload</param-value> </context-param> <context-param> <param-name>javax.faces.VALIDATE_EMPTY_FIELDS</param-name> <param-value>false</param-value> </context-param> 

components.xml (excluding Seam 2.3 namespace declarations

 <core:init jndi-pattern="java:app/myApp/#{ejbName}" debug="false" distributable="false" /> <component class="org.jboss.seam.transaction.EjbSynchronizations" jndi-name="java:app/jboss-seam/EjbSynchronizations" /> <core:manager concurrent-request-timeout="500" conversation-timeout="90000000" conversation-id-parameter="cid" parent-conversation-id-parameter="pid" /> <web:hot-deploy-filter url-pattern="*.seam" /> <web:multipart-filter create-temp-files="true" max-request-size="1000000" url-pattern="/*"/> <persistence:managed-persistence-context name="entityManager" auto-create="true" persistence-unit-jndi-name="java:/myAppEntityManagerFactory" /> <security:identity authenticate-method="#{authenticator.authenticate}" /> <security:remember-me enabled="true" /> <security:rule-based-permission-resolver security-rules="#{securityRules}" /> <drools:rule-base name="securityRules"> <drools:rule-files> <value>/security.drl</value> </drools:rule-files> </drools:rule-base> <async:quartz-dispatcher /> <factory name="sessionTimeoutSeconds" scope="SESSION" value="#{facesContext.externalContext.getSession(true).getMaxInactiveInterval()}" /> <factory name="basePath" value="#{facesContext.externalContext.request.scheme}://#{facesContext.externalContext.request.serverName}: #{facesContext.externalContext.request.serverPort}#{facesContext.externalContext.request.contextPath}" /> <factory name="contextPath" value="#{facesContext.externalContext.request.contextPath}" /> 

Example JSF Source (Seam)

 <h:form enctype="multipart/form-data"> <s:decorate> <s:fileUpload data="#{uploadBean.fileData}" contentType="#{uploadBean.contentType}" fileName="#{uploadBean.fileName}" /> <h:commandButton value="Upload File" type="submit" /> </s:decorate> </h:form> 

Example JSF Source (ICEfaces)

 <h:form enctype="multipart/form-data"> <ace:fileEntry id="file-entry" relativePath="/files/" fileEntryListener="#{uploadBean.uploadFile}" useSessionSubdir="true" /> <h:commandButton id="submit" type="submit" value="Send File" /> </h:form> 

JSF displays a Seam component having byte [] for fileData and String for fileName and contentType. FileEntryListener displays a void method that accepts FileEntryEvent input.


Update

Just to keep you up to date, my findings so far:

Reflecting on BalusC's answer, I looked deeper into the filter material. I already tried to add / remove the Seam Multipart filter, but now I found out that by adding it to components.xml and explicitly disconnecting it through

 <web:multipart-filter disabled="true"/> 

at least something happens with ICEfaces: Exceptions thrown by FileEntryPhaseListener, which was not before:

  09: 26: 19,124 SEVERE [javax.enterprise.resource.webcontainer.jsf.context] (http-
 localhost-127.0.0.1-8080-2) JSF1071: javax.faces.event.AbortProcessingException erfasst 
 während beforePhase () - Verarbeitung von RENDER_RESPONSE 6: UIComponent-ClientId =, Message = /
 template / patient / documents / instantiation / documentInsertPopup.xhtml @ 135.98 
 fileEntryListener = "# {uploadBean.fileUploadListener}": 
 Method not found: 
 my.company.package.stuff.UploadBean@313d
 62f1.fileUploadListener (org.icefaces.ace.component.fileentry.FileEntryEvent)

 09: 26: 19,126 SEVERE [javax.enterprise.resource.webcontainer.jsf.context] (http-
 localhost-127.0.0.1-8080-2) /template/upload.xhtml @ 135.98 fileEntryListener = "#
 {uploadBean.fileUploadListener} ": Method not found: 
 my.company.package.stuff.UploadBean@313d
 62f1.fileUploadListener (org.icefaces.ace.component.fileentry.FileEntryEvent): 
 javax.faces.event.AbortProcessingException: /upload.xhtml @ 135.98 fileEntryListener = "#
 {uploadBean.fileUploadListener} ": Method not found: 
 my.company.package.stuff.UploadBean@313d
 62f1.fileUploadListener (org.icefaces.ace.component.fileentry.FileEntryEvent)

     at org.icefaces.ace.component.fileentry.FileEntry.broadcast (FileEntry.javahaps50) 
 [icefaces-ace.jar:]
     at org.icefaces.ace.component.fileentry.FileEntryPhaseListener $ 1.visit (FileEntryPhaseListener.java:95) [icefaces-ace.jar:]
     at com.sun.faces.component.visit.PartialVisitContext.invokeVisitCallback (PartialVisitContext.java:183) [javax.faces.jar: 2.1.4-FCS]
     at javax.faces.component.UIComponent.visitTree (UIComponent.java:1612) [jboss-jsf-api_2.1_spec-2.0.1.Final.jar: 2.0.1.Final]
     at javax.faces.component.UIComponent.visitTree (UIComponent.java:1623) [jboss-jsf-api_2.1_spec-2.0.1.Final.jar: 2.0.1.Final]
     at javax.faces.component.UIComponent.visitTree (UIComponent.java:1623) [jboss-jsf-api_2.1_spec-2.0.1.Final.jar: 2.0.1.Final]
     at javax.faces.component.UIComponent.visitTree (UIComponent.java:1623) [jboss-jsf-api_2.1_spec-2.0.1.Final.jar: 2.0.1.Final]
     at javax.faces.component.UIComponent.visitTree (UIComponent.java:1623) [jboss-jsf-api_2.1_spec-2.0.1.Final.jar: 2.0.1.Final]
     at javax.faces.component.UIComponent.visitTree (UIComponent.java:1623) [jboss-jsf-api_2.1_spec-2.0.1.Final.jar: 2.0.1.Final]
     at javax.faces.component.UIComponent.visitTree (UIComponent.java:1623) [jboss-jsf-api_2.1_spec-2.0.1.Final.jar: 2.0.1.Final]
     at javax.faces.component.UIForm.visitTree (UIForm.java{71) [jboss-jsf-api_2.1_spec-2.0.1.Final.jar: 2.0.1.Final]
     at javax.faces.component.UIComponent.visitTree (UIComponent.java:1623) [jboss-jsf-api_2.1_spec-2.0.1.Final.jar: 2.0.1.Final]
     at javax.faces.component.UIComponent.visitTree (UIComponent.java:1623) [jboss-jsf-api_2.1_spec-2.0.1.Final.jar: 2.0.1.Final]
     at org.icefaces.ace.component.fileentry.FileEntryPhaseListener.beforePhase (FileEntryPhaseListener.java:100) [icefaces-ace.jar:]
     at com.sun.faces.lifecycle.Phase.handleBeforePhase (Phase.java:228) [javax.faces.jar: 2.1.4-FCS]
     at com.sun.faces.lifecycle.Phase.doPhase (Phase.java:99) [javax.faces.jar: 2.1.4-FCS]
     at com.sun.faces.lifecycle.LifecycleImpl.render (LifecycleImpl.java:139) [javax.faces.jar: 2.1.4-FCS]
     at javax.faces.webapp.FacesServlet.service (FacesServlet.java UP94) [jboss-jsf-api_2.1_spec-2.0.1.Final.jar: 2.0.1.Final]
     at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter (ApplicationFilterChain.java:329) [jbossweb-7.0.13.Final.jar:]
     at org.apache.catalina.core.ApplicationFilterChain.doFilter (ApplicationFilterChain.java:248) [jbossweb-7.0.13.Final.jar:]
     at org.jboss.seam.servlet.SeamFilter $ FilterChainImpl.doFilter (SeamFilter.java:83) [jboss-seam.jar: 2.3.0.Final]
     at org.jboss.seam.web.LoggingFilter.doFilter (LoggingFilter.java:60) [jboss-seam.jar: 2.3.0.Final]
     at org.jboss.seam.servlet.SeamFilter $ FilterChainImpl.doFilter (SeamFilter.java:69) [jboss-seam.jar: 2.3.0.Final]
     at org.jboss.seam.web.ExceptionFilter.doFilter (ExceptionFilter.java:64) [jboss-seam.jar: 2.3.0.Final]
     at org.jboss.seam.servlet.SeamFilter $ FilterChainImpl.doFilter (SeamFilter.java:69) [jboss-seam.jar: 2.3.0.Final]
     at org.jboss.seam.web.RedirectFilter.doFilter (RedirectFilter.java:45) [jboss-seam.jar: 2.3.0.Final]
     at org.jboss.seam.servlet.SeamFilter $ FilterChainImpl.doFilter (SeamFilter.java:69) [jboss-seam.jar: 2.3.0.Final]
     at org.jboss.seam.web.IdentityFilter.doFilter (IdentityFilter.java:40) [jboss-seam.jar: 2.3.0.Final]
     at org.jboss.seam.servlet.SeamFilter $ FilterChainImpl.doFilter (SeamFilter.java:69) [jboss-seam.jar: 2.3.0.Final]
     at org.jboss.seam.servlet.SeamFilter.doFilter (SeamFilter.java:158) [jboss-seam.jar: 2.3.0.Final]
     at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter (ApplicationFilterChain.java:280) [jbossweb-7.0.13.Final.jar:]
     at org.apache.catalina.core.ApplicationFilterChain.doFilter (ApplicationFilterChain.java:248) [jbossweb-7.0.13.Final.jar:]
     at org.apache.catalina.core.StandardWrapperValve.invoke (StandardWrapperValve.java:275) [jbossweb-7.0.13.Final.jar:]
     at org.apache.catalina.core.StandardContextValve.invoke (StandardContextValve.java:161) [jbossweb-7.0.13.Final.jar:]
     at org.jboss.as.jpa.interceptor.WebNonTxEmCloserValve.invoke (WebNonTxEmCloserValve.java:50) [jboss-as-jpa-7.1.1.Final.jar: 7.1.1.Final]
     at org.jboss.as.web.security.SecurityContextAssociationValve.invoke (SecurityContextAssociationValve.java:153) [jboss-as-web-7.1.1.Final.jar: 7.1.1.Final]
     at org.apache.catalina.core.StandardHostValve.invoke (StandardHostValve.java:155) [jbossweb-7.0.13.Final.jar:]
     at org.apache.catalina.valves.ErrorReportValve.invoke (ErrorReportValve.java:102) [jbossweb-7.0.13.Final.jar:]
     at org.apache.catalina.core.StandardEngineValve.invoke (StandardEngineValve.java:109) [jbossweb-7.0.13.Final.jar:]
     at org.apache.catalina.connector.CoyoteAdapter.service (CoyoteAdapter.javahaps68) [jbossweb-7.0.13.Final.jar:]
     at org.apache.coyote.http11.Http11Processor.process (Http11Processor.java:877) [jbossweb-7.0.13.Final.jar:]
     at org.apache.coyote.http11.Http11Protocol $ Http11ConnectionHandler.process (Http11Protocol.java:671) [jbossweb-7.0.13.Final.jar:]
     at org.apache.tomcat.util.net.JIoEndpoint $ Worker.run (JIoEndpoint.java:930) [jbossweb-7.0.13.Final.jar:]
     at java.lang.Thread.run (Thread.java:722) [rt.jar: 1.7.0_06]

At least that's what to see. If I use fileEntryListener as

 fileEntryListener="#{uploadBean.fileUploadListener}" 

the above exception is thrown if I use:

 fileEntryListener="#{uploadBean.fileUploadListener()}" 

He complains that this method requires parameters, and if I use it like:

 fileEntryListener="#{uploadBean.fileUploadListener(null)}" 

exceptions are not thrown, but because the event is null, no files reached my UploadBean. It smells like some problems with the library, but at least something else to look at.

Download bean

There are not many, just:

 @Stateful @Name("uploadBean") @Scope(ScopeType.SESSION) @JndiName(value = "java:app/myApp.jar/UploadBean") public class UploadBean implements IUploadBean { public void fileUploadListener(FileEntryEvent event) { System.out.println("listener called!"); } } 

Listener is also declared in the bean interface.

+4
source share
4 answers

At first, some technical background information: until the upcoming JSF 2.2, the JSF does not support multipart/form-data requests. Therefore, a component library that offers a component for downloading files must create its own Filter . This should correctly analyze multipart/form-data requests and store all the necessary regular data in the HTTP request parameter map and uploaded files as request attributes. Thus, JSF can continue to use request.getParameter() for regular data in the usual way, and the component library itself can receive the downloaded file as a request attribute.

In the case of Seam <s:fileUpload> you will need org.jboss.seam.web.MultipartFilter to parse multipart/form-data . I have never used Seam (or ICEfaces), but Google shows me that you basically need either this in webapp web.xml

 <filter> <filter-name>Seam Multipart Filter</filter-name> <filter-class>org.jboss.seam.web.MultipartFilter</filter-class> </filter> <filter-mapping> <filter-name>Seam Multipart Filter</filter-name> <url-pattern>*.seam</url-pattern> </filter-mapping> 

or this is in Seam components.xml :

 <web:multipart-filter url-pattern="*.seam" /> 

A similar filter must be configured in the ICEfaces component. There is no documentation for ICEfaces 3.x (or my Google / icefaces.com search skills are poor), so I can’t dwell on this in detail.

It is important to remember that an HTTP request can be processed only once (the client will send it only once, and not several times), and therefore you cannot use both multipart/form-data analyzers simultaneously on the same request. The one that starts after the first will receive an empty request area, which will not be processed in all reasonable. Therefore, if you use a component that uses the last filter, then you will not get anything in the model. Make sure that you accidentally or experimentally configure both.

+3
source

I still understand this, but it looks like

 <web:multipart-filter disabled="true" url-pattern="bleh"/> 

doesn't work as expected in my test case components.xml, but

 <component class="org.jboss.seam.web.MultipartFilter"> <property name="disabled">true</property> </component> 

Works to disable MultipartFilter seam.

0
source

Perhaps this may help. What I did was relocate my ear design as a war.

remove multi-page filtering in web.xml and add this to components.xml:

 <web:multipart-filter disabled="true"/> 

sample of my component:

 <ace:panel id="pnl"> <h:form> <ice:panelGrid columns="2" bgcolor="#0063AA"> <ace:fileEntry id="file-entry" useOriginalFilename="true" immediate="true" required="true" requiredMessage="The file is required to submit this form." fileEntryListener="#{imageHome.sampleListener}"/> <h:commandButton type="submit" value="Upload" /> </ice:panelGrid> </h:form> </ace:panel> 

My FileEntryEvent was called.

0
source

I do not use Seam, but I noticed that beans, which I define as JSF beans, use different annotations than what you use.

For bean, I use @ManagedBean. For scope I use @SessionScoped.

-1
source

Source: https://habr.com/ru/post/1441251/


All Articles