4

Update

I'm currently over at the ICEfaces forums to get my problem solved - sadly, none of the provided options led to a solution now, but they indeed gave me some more insight into the whole JSF topic (credits go to BalusC for that, as often :-)).

I will try to keep this thread up to date and post an answer if the problem is finally solved to help others which may encounter it.

My findings so far are:

  • Disabling the Seam Multipart Filter is required because it prevents the fileEntry-component from working correctly
  • I still have some nasty library issues in my application resulting in (silent) ClassLoading-issues: 2 icefaces-ace.jar-files were present, one in EAR/lib and one in EAR/WAR/WEB-INF/lib. Removing the one from WEB-INF results in the component doing nothing, removing the one from EAR/lib results in my app not longer deploying.

When moving all frontend jars (icefaces.jar, icefaces-ace.jar, icefaces-compat.jar) from EAR/lib to WEB-INF/lib, I receive various ClassNotFoundExceptions for the jar-part of my EAR: ValueChangeEvent, RowSelectorEvent etc. could not be found (that means, all those events coming from the view into 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

The whole story

I'm working on an web application, using Seam 2.3 and ICEfaces 3.1.0. That means, JSF2 is being used.

My app is deployed on JBoss AS 7.1.0 as an EAR, containing a JAR for application logic and a WAR for all view related stuff.

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

The only big issue is, when I'm using components to upload files, no matter if I use Seam components or ICEfaces components - in Seam, the uploaded file is always null and in ICEfaces, my fileEntryListener-Method never gets called.

With ICEfaces:

In ICEfaces versions prior to 2.X, there was the ice:inputFile-component which has been removed with 2.X and replaced with ace:fileEntry.

InputFile was working good, but FileEntry does not. My problem is exact the same as described in JSF : Issues with File Upload using Icefaces component - the fileEntryListener is never called. I tried the suggestions there (using enctype="multipart/form-data" on the surrounding form, using h:commandButton for form submission), but it didn't work. The only solution provided was switching to Richfaces, which is not an option for me.

With Seam:

Gladly, Seam has it's own build-in fileUpload-component, s:fileUpload.

It doesn't work either, but at least showed me a spot where to look further. When debugging the doDecode-Methods of this component, I found that my request is no MultipartRequest. Crazy thing! All the forms used for uploading files declare the enctype as multipart/form-data. I think, the same is happening when I'm trying to use the ICEfaces component - no multipart request and that leads to no listeners being called.

So: How do I get this to work? What's the point that no Request comes in as MultipartRequest? Do I miss 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 (leaving out the 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 maps to a Seam component, having a byte[] for fileData and String's for fileName and contentType. The fileEntryListener maps to a void method which takes a FileEntryEvent as input.


Update

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

Thinking about BalusC's answer, I looked deeper into the filter stuff. I already tried to add/remove the Seam Multipart Filter, but now I found out that when I add it in components.xml and explicitly disable it via

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

at least something is happening with ICEfaces: Exceptions are thrown by the FileEntryPhaseListener, what has never happened 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.java:350) 
[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:371) [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:594) [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.java:368) [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 this is something to look at. If I use the fileEntryListener like

fileEntryListener="#{uploadBean.fileUploadListener}"

the above exception is thrown, if I use:

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

It complains that the method requires parameters and if I use it like:

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

no exceptions are thrown, but due to the event being null, no files reach my UploadBean. Smells like some library issues, but at least something else to look at.

Upload bean

Not much happens here, it's simply:

@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 declared in the bean's interface, too.

Community
  • 1
  • 1
Volker
  • 450
  • 5
  • 16
  • Could you post your `UploadBean` class (the icefaces backed version)? The error seems simple: the listener method is not found on the bean. Note that the method must return `void` and have a single `FileEntryEvent` parameter. If either of these is missing, the method will not be found. On your tag, use the `fileEntryListener="#{uploadBean.fileUploadListener}"` version, don't put the parenthesis. – EmirCalabuch Oct 26 '12 at 00:46
  • Yes, it's definitly available, see update. The parantheses-stuff was only done to just make it do at least something, in all other cases in my app, it works with without those and ActionEvents, ValueChangeEvents or whatever are given to the application as it should. – Volker Oct 26 '12 at 06:29

4 Answers4

3

First some technical background information: until the upcoming JSF 2.2, JSF doesn't natively support multipart/form-data requests. So the component library offering the file upload component has to come up with a custom Filter itself. This should properly parse multipart/form-data requests and store all the necessary regular data in the HTTP request parameter map and the uploaded file(s) as request attribute(s). This way JSF can continue using request.getParameter() for regular data the usual way and the component library itself can get the uploaded file(s) as request attribute.

In case of Seam's <s:fileUpload>, you need the org.jboss.seam.web.MultipartFilter to perform the multipart/form-data parsing job. I have never used Seam (nor ICEfaces), but Google shows me that you basically need either this in webapp's 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 in Seam components.xml:

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

The ICEfaces component must have a similar Filter configured. The ICEfaces 3.x documentation is lacking (or my Google / icefaces.com search skills are bad), so I can't go in detail about this.

Important to keep in mind is that a HTTP request can be parsed only once (the client will send it only once, not multiple times) and thus you can't use the both multipart/form-data parsers simultaneously on the same request. The one which kicks in after the first one would get an empty request body which isn't parseable into anything sensible. So if you're using a component which is using the latter filter, then you wouldn't get anything in the model. Make sure that you haven't by accident or by experiment configured both.

BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
  • Thanks for your suggestions - I already tried the Seam Multipart Filter stuff which did not work out, but after your comment I looked deeper into my Filter declarations and found out that disabling the Multipart Filter after adding it at least makes ICEfaces doing something - see Update in question. – Volker Oct 25 '12 at 07:48
  • To confirm, does your `UploadBean` really have the method `fileUploadListener(FileEntryEvent event)`? The exception is telling that this method is missing. Your EL expression is fine btw, the `event` will be automatically supplied. Given the fact that ICEfaces magically works with Seam's filter disabled, it look much like that it's implicitly and silently registering a file upload filter. If you'd prefer to use Seam's one, you might want to look in the ICEfaces documentation if that filter isn't disableable by some context parameter --so that you could if necessary test the Seam one. – BalusC Oct 26 '12 at 02:37
  • Yes, it does. In all other cases in my app, the events are automatically filled in with the listener call, only the FileEntryEvent doesn't want to...e.g. if I call the listener with a parameter of null, it is called and the above message printed out, so at least the method is available somewhere. I think I'll search ICEfaces for the place where the event is raised and see where it goes to, maybe that will help... – Volker Oct 26 '12 at 06:34
  • Coming back to your question update about classloading issues; that might explain it. The `FileEntryEvent` class which is loaded by classloader X is not the same `FileEntryEvent` class which is loaded by classloader Y. It's very reasonable that EL has created the `FileEntryEvent` argument through classloader X and the managed bean class with the upload method is been loaded through classloader Y. This way the method signature will never match. Front-end libraries (ICEfaces/Seam/etc) doesn't belong in EAR/lib and must be in WEB-INF/lib. So if you fix that part, the upload will likely work. – BalusC Oct 31 '12 at 11:00
  • In other words, you should not have duplicates of the same library in different places of the classpath. You mentioned that it didn't deploy when you remove it from EAR/lib. Do you get a concrete exception/error? – BalusC Oct 31 '12 at 11:03
  • Yep, I had a feeling that they are not exactly at the right place there. When moving them to WEB-INF/lib, I receive ClassNotFoundExceptions for those ValueChangeEvent, RowSelectorEvent etc., see update for info and message. – Volker Oct 31 '12 at 11:28
  • Why are your JSF managed beans in a (EJB?) JAR of the EAR? They belong in the WAR. All JSF artifacts (managed beans, converters, listeners, etc) should go in WAR. Only EJB/JPA stuff go in EJB JAR. – BalusC Oct 31 '12 at 11:30
  • I sense something bad coming over, but...I have an EAR which has a JAR with business logic and a WAR with all my XHTML pages. For example, a ValueChangeEvent raised somewhere in the view is received in the backing bean method which is bound to the valueChangeListener property in the view. So, err, where does what belong? – Volker Oct 31 '12 at 11:44
  • The backing bean class should as being a front-end (web) artifact of course go in the WAR. Note that the `ValueChangeEvent` shouldn't be passed through into the business layer at all. You should extract the necessary data from it in the backing bean method and in turn pass the extracted data through to the business layer instead. All your EJB and JPA classes in the EAR/EJB.jar should be absolutely free of any `javax.faces.*` imports/artifacts. – BalusC Oct 31 '12 at 11:46
  • That all makes perfect sense, but...it worked for quite a long time while using ICEfaces 1.8 (which was JSF1) and only popped out when switching to JSF2. Did that change something or is it now just working as intended? – Volker Oct 31 '12 at 11:54
  • Did you also change the appserver? Most appservers can be configured to give classes in EAR precedence over classes in WAR when the WAR needs to load a class. The default is that classes in WAR have precedence. – BalusC Oct 31 '12 at 11:58
  • I moved from JBoss 4.2.2 to 7.1. All events I used in the previous version (like RowSelectorEvent) still work, it's just the FileEntryEvent that is not working (or, I did not stumble over others with this behaviour) – Volker Oct 31 '12 at 12:04
  • Classloading is a complex subject and each appserver has its own set of quirks/rules. But to the point, JSF (front-end) artifacts doesn't belong in business layer (EJB/EAR) at all. It makes them totally unreuseable for other front-ends (e.g. JAX-RS, JSP/Servlet, Struts, JavaSE Swing, etc). I strongly recommend to fix that part and then retest the file upload. – BalusC Oct 31 '12 at 12:06
  • Whoa. At least that gave me something to think about. I thought, that this was what Seam is doing for me (connecting EJBs with the View avoiding those Man in the Middle-objects). I should go and rethink some stuff... – Volker Oct 31 '12 at 12:43
  • Before the bounty expires, I'll reward it to you for providing me with deep insights into various things related to my subject and further, even though the final solution will still need more time. Thanks! – Volker Nov 01 '12 at 10:28
0

I'm still in the process of investigating this, but it looks like

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

is not working as expected in my test case components.xml, but

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

is working to disable the seam MultipartFilter.

Ted Goddard
  • 229
  • 2
  • 3
  • Disabling the multipart filter is required for the fileEntry-component to work. Your options are bot equivalent, but for the web:-Part you must include the correct namespace - at least for me, they both work. – Volker Oct 31 '12 at 09:30
  • I believe we either need to add a POJO variant for ace:fileEntry (this is the approach taken by ICEmobile, a file upload "value" is a Map containing "file"=java.io.File and "type"=String content-type) or split icefaces-ace.jar into api and impl. Personally I'm in favour of a POJO variant since the custom types are rarely used and POJO beans are generally easier to work with. – Ted Goddard Oct 31 '12 at 16:20
0

Maybe it might help. What i did was redeploy my ear project as war.

remove multipart 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 has been called.

-1

I do not use Seam but I noticed the beans that I define as JSF beans are using different annotations than what you are using.

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

BobS
  • 1
  • The Name and Scope annotations are the Seam-way of saying: "I'm a session scoped managed bean", so everything is ok here :-) – Volker Oct 31 '12 at 09:33