Browser-based file uploads, in particular those involving the
HTML <input type="file"> tag, have always been
rather lacking. As I am sure most of you are aware, uploading files
exceeding 10MB often causes a very poor user experience. Once a
user submits the file, the browser will appear to be inactive while
it attempts to upload the file to the server. While this happening
in the background, many impatient users would start to assume that
the server is "hanging" and would try to submit the file again.
This of course, only helps to make matters worse.
In an attempt to make uploading of files more user-friendly,
many sites display an indeterminate progress animation (such as a
rotating icon) once the user submits the file. Although this
technique may be useful in keeping the user distracted while the
upload being submitted to the server, it offers very little
information on the status of the file upload. Another attempt at
solving the problem is to implement an applet that uploads the file
to the server through FTP. The drawback with this solution is that
it limits your audience to those that have a Java-enabled
browser.
In this article, we will take fresh approach and implement an
AJAX-powered component that will not only upload the file to
server, but also monitor the actual progress of a file upload
request in "real time." The four stages of this component are
illustrated below, in Figures 1, 2, 3, and 4:
Figure 1. Stage 1: Selecting the file upload
Figure 2. Stage 2: Uploading the file to the server
Figure 3. Stage 3: Uploaded completed
Figure 4. File upload summary
Implementing the Component
We will first walk through the process of creating the multipart
filter that will allow us to handle and monitor the file upload. We
will then move on to implementation of the JavaServer Faces
component that will provide the user with continuous feedback in
the form of an AJAX-enabled progress bar.
The Multipart Filter: UploadMultipartFilter
The responsibility of the multipart filter is to intercept the
incoming file upload and write the file to a temporary directory on
the server. At the same time, it will also monitor the amount of
bytes received and determine how much of the file has been
uploaded. Fortunately, there is an excellent Jakarta-Commons open
source library available (FileUpload)
that takes care of parsing an HTTP multipart request and writing a
file upload to disk. We will be extend this library and add in the
required "hooks" we need to monitor how many bytes have been
processed.
public class UploadMultipartFilter implements Filter{
public void doFilter(ServletRequest request,
ServletResponse response,
FilterChain chain)
throws IOException, ServletException {
HttpServletRequest hRequest = (HttpServletRequest)request;
//Check whether we're dealing with a multipart request
String contentHeader = hRequest.getHeader("content-type");
boolean isMultipart = ( contentHeader != null &&
contentHeader.indexOf("multipart/form-data") != -1);
if(isMultipart == false){
chain.doFilter(request,response);
}else{
UploadMultipartRequestWrapper wrapper =
new UploadMultipartRequestWrapper(hRequest);
chain.doFilter(wrapper,response);
}
...
}
As you can see, the UploadMultipartFilter class
simply checks to see whether the current request is a multipart
request. If the request does not contain a file upload, the request
is passed on to the next filter in the chain without any additional
processing. Otherwise, the request is wrapped in an
UploadMultipartRequestWrapper.
The UploadMultipartRequestWrapper Class
public class UploadMultipartRequestWrapper
extends HttpServletRequestWrapper{
private Map<String,String> formParameters;
private Map<String,FileItem> fileParameters;
public UploadMultipartRequestWrapper(HttpServletRequest request) {
super(request);
try{
ServletFileUpload upload = new ServletFileUpload();
upload.setFileItemFactory(new ProgressMonitorFileItemFactory(request));
List fileItems = upload.parseRequest(request);
formParameters = new HashMap<String,String>();
fileParameters = new HashMap<String,FileItem>();
for(int i=0;i<fileItems.size();i++){
FileItem item = (FileItem)fileItems.get(i);
if(item.isFormField() == true){
formParameters.put(item.getFieldName(),item.getString());
}else{
fileParameters.put(item.getFieldName(),item);
request.setAttribute(item.getFieldName(),item);
}
}
}catch(FileUploadException fe){
//Request Timed out - user might have gone to other page.
//Do some logging
//...
}
...
In our UploadMultipartRequestWrapper class, we
initialize the commons
ServletFileUpload class that will parse our request and write the file to the default temporary directory on the server.
The
ServletFileUpload instance creates a
FileItem instance for each field that is encountered in
the request. These include both file uploads and normal form
elements. A
FileItem instance can then be used to retrieve the
properties of a submitted field, or, in the case of a file upload,
an InputStream to the underlying temporary file to which it has been saved. In summary, the
UploadMultipartRequestWrapper basically parses the
file and sets any
FileItems that represent file uploads as attributes in
the request. These can then be picked up by JSF components further
down the line. The behavior of normal form fields remains the
same.
By default, the Commons FileUpload
library use instances of the
DiskFileItems class to handle file uploads. Although
DiskFileItems are very useful in handling the whole
temporary-file business, there is very little support for
monitoring exactly how much of the file has been processed. Since
version 1.1, the Commons FileUpload
library provides developers with the ability to specify the
factory that will be used to create the
FileItem. We will use the
ProgressMonitorFileItemFactory and
ProgressMonitorFileItem classes to override the
default behavior and monitor the progress file uploads.
The ProgressMonitorFileItemFactory Class
public class ProgressMonitorFileItemFactory
extends DiskFileItemFactory {
private File temporaryDirectory;
private HttpServletRequest requestRef;
private long requestLength;
public ProgressMonitorFileItemFactory(HttpServletRequest request) {
super();
temporaryDirectory = (File)request.getSession().getServletContext().
getAttribute("javax.servlet.context.tempdir");
requestRef = request;
String contentLength = request.getHeader("content-length");
if(contentLength != null){
requestLength = Long.parseLong(contentLength.trim());
}
}
public FileItem createItem(String fieldName, String contentType,
boolean isFormField, String fileName) {
SessionUpdatingProgressObserver observer = null;
if(isFormField == false) //This must be a file upload.
observer = new SessionUpdatingProgressObserver(fieldName,
fileName);
ProgressMonitorFileItem item = new ProgressMonitorFileItem(
fieldName,
contentType,
isFormField,
fileName,
2048,
temporaryDirectory,
observer,
requestLength);
return item;
}
...
public class SessionUpdatingProgressObserver
implements ProgressObserver {
private String fieldName;
private String fileName;
...
public void setProgress(double progress) {
if(request != null){
request.getSession().setAttribute("FileUpload.Progress." + fieldName,
progress);
request.getSession().setAttribute("FileUpload.FileName." + fieldName,
fileName);
}
}
}
}
The ProgressMonitorFileItemFactory uses the
Content-Length header set by the browser and assumes it to be the
accurate length of the upload file being sent. This method of
determining the file length does limit you to uploading only one
file per request--it's inaccurate if more than more file is
encoded in the request. This is due to the fact that browsers only
send one Content-Length header, regardless of the number of files
in the upload.
In addition to creating ProgressMonitorFileItem
instances, the ProgressMonitorFileItemFactory also
registers a ProgressObserver instance that will be
used by the ProgressMonitorFileItem to send updates on
the progress of the file upload. The implementation of the
ProgressObserver used,
SessionUpdatingProgressObserver, sets the progress
percentage into the user's session under the id of the submitted
field. This value can then be accessed by the JSF component in
order to send updates to the user.
The ProgressMonitorFileItem Class
public class ProgressMonitorFileItem extends DiskFileItem {
private ProgressObserver observer;
private long passedInFileSize;
...
private boolean isFormField;
...
@Override
public OutputStream getOutputStream() throws IOException {
OutputStream baseOutputStream = super.getOutputStream();
if(isFormField == false){
return new BytesCountingOutputStream(baseOutputStream);
}else{
return baseOutputStream;
}
}
...
private class BytesCountingOutputStream extends OutputStream{
private long previousProgressUpdate;
private OutputStream base;
public BytesCountingOutputStream(OutputStream ous){
base = ous;
}
...
private void fireProgressEvent(int b){
bytesRead += b;
...
double progress = (((double)(bytesRead)) / passedInFileSize);
progress *= 100.0
observer.setProgress();
}
}
}
The ProgressMonitorFileItem wraps the default
OutputStream of the
DiskFileItem in a
BytesCountingOutputStream, which updates the
associated ProgressObserver every time a certain
number of bytes have been read.
The AJAX-Enabled JavaServer Faces Upload Component
This component is responsible for rendering the HTML file upload
tag, displaying a progress bar to monitor the file upload, and
rendering the components that need to be displayed once a file has
been successfully uploaded. One of the main advantages to
implementing this component using JavaServer Faces is the fact that
most of the complexities are hidden from the page author. The page
author only needs to add the component tag to the JSP and the
component will take care of all of the AJAX and progress-monitoring
details. Below is the JSP code snippet that is used to add the
upload component to the page.
<comp:fileUpload
value="#{uploadPageBean.uploadedFile}"
uploadIcon="images/upload.png"
styleClass="progressBarDiv"
progressBarStyleClass="progressBar"
cellStyleClass="progressBarCell"
activeStyleClass="progressBarActiveCell">
<%--Below are the components that will be
visible once the file upload completes--%>
<h:panelGrid columns="2" cellpadding="2" cellspacing="0" width="100%">
<f:facet name="header">
<h:outputText styleClass="text"
value="File Upload Successful." />
</f:facet>
<h:panelGroup style="text-align:left;display:block;width:100%;">
<h:commandButton action="#{uploadPageBean.reset}"
image="images/reset.png"/>
</h:panelGroup>
<h:panelGroup style="text-align:right;display:block;width:100%;">
<h:commandButton action="#{uploadPageBean.nextPage}"
image="images/continue.png"/>
</h:panelGroup>
</h:panelGrid>
</comp:fileUpload>
The value attribute of the file upload component
needs to be bound to a bean with a property that holds a
FileItem. The child components are only displayed once
the file has been successfully received by the server.
Implementing the AJAX File Upload Component
The progress bar of the component was inspired by the "
Progress Bar Using JavaServer Faces Component with AJAX"
solution as detailed in the Java
BluePrints Solution Catalog. In essence, the upload component
either renders a complete version of itself, or in the case of an
AJAX request, only a bit of XML to update the state of the progress
bar on the page. In order to prevent JavaServer Faces from
rendering the complete component tree (which would incur
unnecessary overhead), we also need to implement a
PhaseListener (PagePhaseListener) to abort
the rest of the faces' request processing if an AJAX request is
encountered. I have omitted all of the standard configuration
(faces-config.xml and tag libraries) from the article, as
these are very straightforward and have been covered
before. Everything is, however, included in the source code
download for this article (in the Resources section) if you wish to review them.
The AJAX File Upload Component Renderer
The implementation of the component and tag classes is rather
straightforward. The bulk of the logic is contained in the
renderer, which has the following responsibilities:
Encode the full file upload component (complete with the HTML
file upload tag), components to be displayed once a file has been
uploaded, and the client-side JavaScript code to implement for the
AJAX requests.
Handle partial AJAX requests appropriately and send back the
necessary XML.
Decode a file upload and set it as a
FileItem instance on the underlying value binding.
Encoding the Full Upload Component
As mentioned previously, the file upload component is composed of
three stages. During the full encoding of the component, we will
encode all three stages. Their visibility (using the CSS display
property) on the page will then be controlled by the AJAX
JavaScript.
Stage 1
Figure 5 shows stage 1 of the upload component.
Figure 5. Stage 1: Selecting the file upload
In Stage 1, we need to render the HTML file upload tag and the
button that will be responsible for starting off this process. Once
the user clicks the upload button, the form is submitted through an
IFRAME ( to prevent blocking on the page) and the second stage of
the process is initiated. Below is an extract of the rendering code
:
//The File upload component
writer.startElement("input", component);
writer.writeAttribute("type", "file", null);
writer.writeAttribute("name", component.getClientId(context), "id");
writer.writeAttribute("id", component.getClientId(context),"id");
if(input.getValue() != null){
//Render the name of the file if available.
FileItem fileData = (FileItem)input.getValue();
writer.writeAttribute("value", fileData.getName(), fileData.getName());
}
writer.endElement("input");
String iconURL = input.getUploadIcon();
//Render the image, and attach the JavaScript event to it.
writer.startElement("div", component);
writer.writeAttribute("style","display:block;width:100%;text-align:center;", "style");
writer.startElement("img", component);
writer.writeAttribute("src",iconURL,"src");
writer.writeAttribute("type","image","type");
writer.writeAttribute("style","cursor:hand;cursor:pointer;","style");
UIForm form = FacesUtils.getForm(context,component);
if(form != null) {
String getFormJS = "document.getElementById('" + form.getClientId(context) + "')";
String jsFriendlyClientID = input.getClientId(context).replace(":","_");
//Sets the encoding of the form to be multipart required for file uploads and
//to submit its content through an IFRAME. The second stage of the component is
//also initialized after 500 milliseconds.
writer.writeAttribute("onclick",getFormJS + ".encoding='multipart/form-data';" +
getFormJS + ".target='" + iframeName + "';" + getFormJS + ".submit();" +
getFormJS + ".encoding='application/x-www-form-urlencoded';" +
getFormJS + ".target='_self';" +
"setTimeout('refreshProgress" + jsFriendlyClientID + "();',500);",
null);
}
...
writer.endElement("img");
//Now do the IFRAME we are going to submit the file/form to.
writer.startElement("iframe", component);
writer.writeAttribute("id", iframeName, null);
writer.writeAttribute("name",iframeName,null);
writer.writeAttribute("style","display:none;",null);
writer.endElement("iframe");
writer.endElement("div");
writer.endElement("div"); //End of Stage1
Stage 2
Stage 2 of the component is the progress bar and the label that
indicates the current percentage, as seen in Figure 6. The progress
bar is implemented as a div tag with 100
embedded span tags. These will be set by the AJAX
JavaScript based on the response received from the server.
Figure 6. Stage 2: Uploading the file to the server
Finally, the components that need to be displayed once a
file has been successfully uploaded, seen in Figure 7, are rendered
as part of Stage 3. These are done in the
encodeChildren method of the renderer.
Figure 7. Stage 3: Uploaded completed
public void encodeChildren(FacesContext context,
UIComponent component) throws IOException {
ResponseWriter writer = context.getResponseWriter();
UIFileUpload input = (UIFileUpload)component;
//Do the children that will be shown once the
//file has been successfully uploaded
writer.startElement("div", component);
writer.writeAttribute("id", input.getClientId(context) + "_stage3", "id"); //Stage3.
if(input.getValue() == null){
writer.writeAttribute("style","display:none;",null);
}else{
writer.writeAttribute("style","display:block",null);
}
List<UIComponent> children = input.getChildren();
for(UIComponent child : children){
FacesUtils.encodeRecursive(context,child);
}
writer.endElement("div"); //End of Stage3
}
Handling AJAX Requests
The rendering of AJAX requests is handled in the
decode method of this component, in accordance with
recommendations in the Java
BluePrints Solution Catalog. We need to check whether this is
in fact an AJAX request (to differentiate from normal decoding
behavior) and then send back an XML response to the client based on
the values that have been set in the session by the
SessionUpdatingProgressObserver instance in the
ProgressMonitorFileItemFactory class.
public void decode(FacesContext context, UIComponent component) {
UIFileUpload input = (UIFileUpload) component;
//Check whether this is a request for the
//progress of the upload, or if it is an actual
// upload request.
ExternalContext extContext = context.getExternalContext();
Map parameterMap = extContext.getRequestParameterMap();
String clientId = input.getClientId(context);
Map requestMap = extContext.getRequestParameterMap();
if(requestMap.get(clientId) == null){
//Nothing to do.
return;
}
if(parameterMap.containsKey(PROGRESS_REQUEST_PARAM_NAME)){
//This is a request to get the progress on the file request.
//Get the progress and render it as XML
HttpServletResponse response = (HttpServletResponse)
context.getExternalContext().getResponse();
// set the header information for the response
response.setContentType("text/xml");
response.setHeader("Cache-Control", "no-cache");
try {
ResponseWriter writer = FacesUtils.setupResponseWriter(context);
writer.startElement("progress", input);
writer.startElement("percentage", input);
//Get the current progress percentage from
//the session (as set by the filter).
Double progressCount = (Double)extContext.getSessionMap().
get("FileUpload.Progress." +
input.getClientId(context));
if(progressCount != null){
writer.writeText(progressCount, null);
}else{
//We haven't received the upload yet.
writer.writeText("1", null);
}
writer.endElement("percentage");
writer.startElement("clientId", input);
writer.writeText(input.getClientId(context), null);
writer.endElement("clientId");
writer.endElement("progress");
} catch(Exception e){
//Do some sort of error logging...
}
}else{
//Normal decoding request.
...
Normal Decoding Behavior
During normal decoding, the file upload renderer retrieves the
FileItem from the request attributes, where it has been
set by the filter, and updates the component's value binding. The
progress in the session is then updated to 100 percent so that the
JavaScript on the page can move the component into Stage 3.
//Normal decoding request.
if(requestMap.get(clientId).toString().equals("file")){
try{
HttpServletRequest request = (HttpServletRequest)extContext.getRequest();
FileItem fileData = (FileItem)request.getAttribute(clientId);
if(fileData != null) input.setSubmittedValue(fileData);
//Now we need to clear any progress associated with this item.
extContext.getSessionMap().put("FileUpload.Progress." +
input.getClientId(context),
new Double(100));
}catch(Exception e){
throw new RuntimeException("Could not handle file upload" +
" - please configure the filter.",e);
}
}
The client-side JavaScript is responsible for making progress
requests to the server and for moving the component through the
different stages. To cut out the usual boilerplate code associated
with handling all of the browser-specific quirks of the XMLHttpRequest
object, I've opted for the excellent AjaxRequest.js library provided
by Matt Krause. This library allows us to considerably reduce the
amount of JavaScript code we need to write to get this component
working. Although it is probably best practice to package the
JavaScript code as part of the component and then to render it from
a
PhaseListener (as detailed here
), I've tried to keep it simple by defining a link to the
JavaScript library on the JSP page.
The getProgressBarJavaScript method in the
component is called to render the JavaScript. Getting the
JavaScript correct is usually the most painful part of implementing
any AJAX component; hopefully, the code below is clear enough to
be easily understood. While the JavaScript in my example is
embedded within the Java code, it is probably better practice to
externalize it into a separate file. For the purposes of this
article I wanted to keep it simple and to the point. Below is an
example of the JavaScript that would be rendered by the component.
It is assumed that fileUpload1 is the client-side JSF Id assigned
to the file component, while uploadForm is the Id of the HTML
form.
function refreshProgress(){
// Assume we are entering stage 2.
document.getElementById('fileUpload1_stage1').style.display = 'none';
document.getElementById('fileUpload1_stage2').style.display = '';
document.getElementById('fileUpload1_stage3').style.display = 'none';
// Create the AJAX post
AjaxRequest.post(
{
//Specify the correct parameters so that
//the component is correctly handled on
//the server side.
'parameters':{ 'uploadForm':'uploadForm',
'fileUpload1':'fileUpload1',
'jsf.component.UIFileUpload':'1',
'ajax.abortPhase':'4' } //Abort at Phase 4.
// Specify the callback method for successful processing.
,'onSuccess':function(req) {
var xml = req.responseXML;
if( xml.getElementsByTagName('clientId').length == 0) {
setTimeout('refreshProgress()',200);
return;
}
var clientId = xml.getElementsByTagName('clientId');
clientId = clientId[0].firstChild.nodeValue + '_progressBar';
//Get the percentage from the XML
var percentage = xml.getElementsByTagName('percentage')[0].firstChild.nodeValue;
var innerSpans = document.getElementById(clientId).getElementsByTagName('span');
document.getElementById(clientId + 'label').innerHTML = Math.round(percentage) + '%';
// Set the style classes of the spans based on the current progress.
for(var i=0;i<innerSpans.length;i++){
if(i < percentage){
innerSpans[i].className = 'active';
}else{
innerSpans[i].className = 'passive';
}
}
// If the percentage is not 100, we need to carry
// on polling the server for updates.
if(percentage != 100){
setTimeout('refreshProgress()',400);
} else {
// The file upload is done - we now
//need to move the component into stage 3.
document.getElementById('fileUpload1_stage1').style.display = 'none';
document.getElementById('fileUpload1_stage2').style.display = 'none';
document.getElementById('fileUpload1_stage3').style.display = '';
}
}
});
}
return builder.toString();
Conclusion
Hopefully, this article offered you some insight on how to make
file uploads more user-friendly, and on the possibilities of
combining AJAX and JavaServer Faces for advanced user interface
components. The solution in this article is by no means exhaustive
and could probably be further improved. I would encourage you to
look at the complete source code to gain a deeper understanding of
the concepts discussed here.
Ajax Toolbox for more
information on the AjaxRequest API used in this article
Jacobus Steenkamp has been developing in Java for the last 4.5 years and has worked in various sectors including the financial, pharmaceutical and energy industries.
What do you think of this combination of AJAX and JSF?
Showing messages 1 through 61 of 61.
I got exception while running your app
2008-04-10 06:14:03 rashidmdk
[Reply | View]
I am using my eclipse and i have added all the files of your api and also list of jar files that you mentioned in the file. But i am getting the following exception
17:36:10,562 ERROR [[/FileUploader4]] Exception sending context initialized event to listener instance of class com.sun.faces.config.ConfigureListener
javax.faces.FacesException: java.lang.ClassCastException: org.apache.myfaces.renderkit.html.util.ExtensionsPhaseListener
at com.sun.faces.config.ConfigureListener.contextInitialized(ConfigureListener.java:310)
at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:3729)
at org.apache.catalina.core.StandardContext.start(StandardContext.java:4187)
at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:759)
at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:739)
at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:524)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.apache.commons.modeler.BaseModelMBean.invoke(BaseModelMBean.java:503)
at org.jboss.mx.server.RawDynamicInvoker.invoke(RawDynamicInvoker.java:164)
at org.jboss.mx.server.MBeanServerImpl.invoke(MBeanServerImpl.java:659)
at org.apache.catalina.core.StandardContext.init(StandardContext.java:5116)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.apache.commons.modeler.BaseModelMBean.invoke(BaseModelMBean.java:503)
at org.jboss.mx.server.RawDynamicInvoker.invoke(RawDynamicInvoker.java:164)
at org.jboss.mx.server.MBeanServerImpl.invoke(MBeanServerImpl.java:659)
at org.jboss.web.tomcat.tc5.TomcatDeployer.performDeployInternal(TomcatDeployer.java:297)
at org.jboss.web.tomcat.tc5.TomcatDeployer.performDeploy(TomcatDeployer.java:103)
at org.jboss.web.AbstractWebDeployer.start(AbstractWebDeployer.java:371)
at org.jboss.web.WebModule.startModule(WebModule.java:83)
at org.jboss.web.WebModule.startService(WebModule.java:61)
at org.jboss.system.ServiceMBeanSupport.jbossInternalStart(ServiceMBeanSupport.java:289)
at org.jboss.system.ServiceMBeanSupport.jbossInternalLifecycle(ServiceMBeanSupport.java:245)
at sun.reflect.GeneratedMethodAccessor37.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.jboss.mx.interceptor.ReflectedDispatcher.invoke(ReflectedDispatcher.java:155)
at org.jboss.mx.server.Invocation.dispatch(Invocation.java:94)
at org.jboss.mx.server.Invocation.invoke(Invocation.java:86)
at org.jboss.mx.server.AbstractMBeanInvoker.invoke(AbstractMBeanInvoker.java:264)
at org.jboss.mx.server.MBeanServerImpl.invoke(MBeanServerImpl.java:659)
at org.jboss.system.ServiceController$ServiceProxy.invoke(ServiceController.java:978)
at $Proxy0.start(Unknown Source)
at org.jboss.system.ServiceController.start(ServiceController.java:417)
at sun.reflect.GeneratedMethodAccessor9.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.jboss.mx.interceptor.ReflectedDispatcher.invoke(ReflectedDispatcher.java:155)
at org.jboss.mx.server.Invocation.dispatch(Invocation.java:94)
at org.jboss.mx.server.Invocation.invoke(Invocation.java:86)
at org.jboss.mx.server.AbstractMBeanInvoker.invoke(AbstractMBeanInvoker.java:264)
at org.jboss.mx.server.MBeanServerImpl.invoke(MBeanServerImpl.java:659)
at org.jboss.mx.util.MBeanProxyExt.invoke(MBeanProxyExt.java:210)
at $Proxy30.start(Unknown Source)
at org.jboss.web.AbstractWebContainer.start(AbstractWebContainer.java:466)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.jboss.mx.interceptor.ReflectedDispatcher.invoke(ReflectedDispatcher.java:155)
at org.jboss.mx.server.Invocation.dispatch(Invocation.java:94)
at org.jboss.mx.interceptor.AbstractInterceptor.invoke(AbstractInterceptor.java:133)
at org.jboss.mx.server.Invocation.invoke(Invocation.java:88)
at org.jboss.mx.interceptor.ModelMBeanOperationInterceptor.invoke(ModelMBeanOperationInterceptor.java:142)
at org.jboss.mx.interceptor.DynamicInterceptor.invoke(DynamicInterceptor.java:97)
at org.jboss.system.InterceptorServiceMBeanSupport.invokeNext(InterceptorServiceMBeanSupport.java:238)
at org.jboss.ws.server.WebServiceDeployer.start(WebServiceDeployer.java:117)
at org.jboss.deployment.SubDeployerInterceptorSupport$XMBeanInterceptor.start(SubDeployerInterceptorSupport.java:188)
at org.jboss.deployment.SubDeployerInterceptor.invoke(SubDeployerInterceptor.java:95)
at org.jboss.mx.server.Invocation.invoke(Invocation.java:88)
at org.jboss.mx.server.AbstractMBeanInvoker.invoke(AbstractMBeanInvoker.java:264)
at org.jboss.mx.server.MBeanServerImpl.invoke(MBeanServerImpl.java:659)
at org.jboss.mx.util.MBeanProxyExt.invoke(MBeanProxyExt.java:210)
at $Proxy31.start(Unknown Source)
at org.jboss.deployment.MainDeployer.start(MainDeployer.java:1007)
at org.jboss.deployment.MainDeployer.deploy(MainDeployer.java:808)
at org.jboss.deployment.MainDeployer.deploy(MainDeployer.java:771)
at sun.reflect.GeneratedMethodAccessor53.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.jboss.mx.interceptor.ReflectedDispatcher.invoke(ReflectedDispatcher.java:155)
at org.jboss.mx.server.Invocation.dispatch(Invocation.java:94)
at org.jboss.mx.interceptor.AbstractInterceptor.invoke(AbstractInterceptor.java:133)
at org.jboss.mx.server.Invocation.invoke(Invocation.java:88)
at org.jboss.mx.interceptor.ModelMBeanOperationInterceptor.invoke(ModelMBeanOperationInterceptor.java:142)
at org.jboss.mx.server.Invocation.invoke(Invocation.java:88)
at org.jboss.mx.server.AbstractMBeanInvoker.invoke(AbstractMBeanInvoker.java:264)
at org.jboss.mx.server.MBeanServerImpl.invoke(MBeanServerImpl.java:659)
at org.jboss.mx.util.MBeanProxyExt.invoke(MBeanProxyExt.java:210)
at $Proxy8.deploy(Unknown Source)
at org.jboss.deployment.scanner.URLDeploymentScanner.deploy(URLDeploymentScanner.java:421)
at org.jboss.deployment.scanner.URLDeploymentScanner.scan(URLDeploymentScanner.java:634)
at org.jboss.deployment.scanner.AbstractDeploymentScanner$ScannerThread.doScan(AbstractDeploymentScanner.java:263)
at org.jboss.deployment.scanner.AbstractDeploymentScanner.startService(AbstractDeploymentScanner.java:336)
at org.jboss.system.ServiceMBeanSupport.jbossInternalStart(ServiceMBeanSupport.java:289)
at org.jboss.system.ServiceMBeanSupport.jbossInternalLifecycle(ServiceMBeanSupport.java:245)
at sun.reflect.GeneratedMethodAccessor8.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.jboss.mx.interceptor.ReflectedDispatcher.invoke(ReflectedDispatcher.java:155)
at org.jboss.mx.server.Invocation.dispatch(Invocation.java:94)
at org.jboss.mx.server.Invocation.invoke(Invocation.java:86)
at org.jboss.mx.server.AbstractMBeanInvoker.invoke(AbstractMBeanInvoker.java:264)
at org.jboss.mx.server.MBeanServerImpl.invoke(MBeanServerImpl.java:659)
at org.jboss.system.ServiceController$ServiceProxy.invoke(ServiceController.java:978)
at $Proxy0.start(Unknown Source)
at org.jboss.system.ServiceController.start(ServiceController.java:417)
at sun.reflect.GeneratedMethodAccessor9.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.jboss.mx.interceptor.ReflectedDispatcher.invoke(ReflectedDispatcher.java:155)
at org.jboss.mx.server.Invocation.dispatch(Invocation.java:94)
at org.jboss.mx.server.Invocation.invoke(Invocation.java:86)
at org.jboss.mx.server.AbstractMBeanInvoker.invoke(AbstractMBeanInvoker.java:264)
at org.jboss.mx.server.MBeanServerImpl.invoke(MBeanServerImpl.java:659)
at org.jboss.mx.util.MBeanProxyExt.invoke(MBeanProxyExt.java:210)
at $Proxy4.start(Unknown Source)
at org.jboss.deployment.SARDeployer.start(SARDeployer.java:302)
at org.jboss.deployment.MainDeployer.start(MainDeployer.java:1007)
at org.jboss.deployment.MainDeployer.deploy(MainDeployer.java:808)
at org.jboss.deployment.MainDeployer.deploy(MainDeployer.java:771)
at org.jboss.deployment.MainDeployer.deploy(MainDeployer.java:755)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.jboss.mx.interceptor.ReflectedDispatcher.invoke(ReflectedDispatcher.java:155)
at org.jboss.mx.server.Invocation.dispatch(Invocation.java:94)
at org.jboss.mx.interceptor.AbstractInterceptor.invoke(AbstractInterceptor.java:133)
at org.jboss.mx.server.Invocation.invoke(Invocation.java:88)
at org.jboss.mx.interceptor.ModelMBeanOperationInterceptor.invoke(ModelMBeanOperationInterceptor.java:142)
at org.jboss.mx.server.Invocation.invoke(Invocation.java:88)
at org.jboss.mx.server.AbstractMBeanInvoker.invoke(AbstractMBeanInvoker.java:264)
at org.jboss.mx.server.MBeanServerImpl.invoke(MBeanServerImpl.java:659)
at org.jboss.mx.util.MBeanProxyExt.invoke(MBeanProxyExt.java:210)
at $Proxy5.deploy(Unknown Source)
at org.jboss.system.server.ServerImpl.doStart(ServerImpl.java:482)
at org.jboss.system.server.ServerImpl.start(ServerImpl.java:362)
at org.jboss.Main.boot(Main.java:200)
at org.jboss.Main$1.run(Main.java:464)
at java.lang.Thread.run(Unknown Source)
Caused by: java.lang.ClassCastException: org.apache.myfaces.renderkit.html.util.ExtensionsPhaseListener
at com.sun.faces.config.ConfigureListener.configure(ConfigureListener.java:699)
at com.sun.faces.config.ConfigureListener.configure(ConfigureListener.java:371)
at com.sun.faces.config.ConfigureListener.contextInitialized(ConfigureListener.java:306)
... 135 more
problem with compiling
2008-02-27 14:24:51 hati102
[Reply | View]
Ello.
I have some problems with compiling source code.
I have all required jars:
commons-beanutils.jar
commons-collections.jar
commons-digester.jar
commons-fileupload-1.1.jar
commons-io-1.1.jar
commons-lang.jar
jsf-api.jar
jsf-impl.jar
jstl.jar
and j2ee.jar
and when I run ant with build.xml, i get this error messages:
[javac] Compiling 11 source files to E:\eclipse_3.2.2\workspace\ajaxuploadoryg\build
[javac] E:\eclipse_3.2.2\workspace\ajaxuploadoryg\src\jsf\FacesUtils.java:55: '(' or '[' expected
[javac] List<UIForm> forms = new ArrayList<UIForm>();
[javac] ^
[javac] E:\eclipse_3.2.2\workspace\ajaxuploadoryg\src\jsf\FacesUtils.java:80: <identifier> expected
[javac] private static void findSubForms(FacesContext context, UIComponent component, List<UIForm> forms){
[javac] ^
[javac] E:\eclipse_3.2.2\workspace\ajaxuploadoryg\src\jsf\FacesUtils.java:105: ')' expected
[javac] ^
[javac] E:\eclipse_3.2.2\workspace\ajaxuploadoryg\src\jsf\component\FileUploadRenderer.java:225: illegal character: \64
[javac] @Override
[javac] ^
[javac] E:\eclipse_3.2.2\workspace\ajaxuploadoryg\src\jsf\component\FileUploadRenderer.java:244: illegal character: \64
[javac] @Override
[javac] ^
[javac] E:\eclipse_3.2.2\workspace\ajaxuploadoryg\src\jsf\component\FileUploadRenderer.java:313: <identifier> expected
[javac] ^
[javac] E:\eclipse_3.2.2\workspace\ajaxuploadoryg\src\upload\ProgressMonitorFileItem.java:28: illegal character: \64
[javac] @Override
etc (19 errors)
What's the problem? JDK 1,4, eclipse 3.2.2, all libraries in classpath.
What's wrong?
NULLPointer exception Argument Error: One or more parameters are null.
2007-12-12 15:17:29 naatlik
[Reply | View]
I am using Tomcat 6.0 and Jsf1.1
I've checked all jars recommened are in place.
Can you help me, please?
I am getting :java.lang.NullPointerException: Argument Error: One or more parameters are null.
at com.sun.faces.renderkit.html_basic.HtmlResponseWriter.writeAttribute(HtmlResponseWriter.java:260)
at jsf.component.FileUploadRenderer.encodeEnd(FileUploadRenderer.java:144)
at javax.faces.component.UIComponentBase.encodeEnd(UIComponentBase.java:713)
at com.sun.faces.renderkit.html_basic.HtmlBasicRenderer.encodeRecursive(HtmlBasicRenderer.java:473)
at com.sun.faces.renderkit.html_basic.GridRenderer.encodeChildren(GridRenderer.java:253)
at javax.faces.component.UIComponentBase.encodeChildren(UIComponentBase.java:694)
at javax.faces.webapp.UIComponentTag.encodeChildren(UIComponentTag.java:590)
at javax.faces.webapp.UIComponentTag.doEndTag(UIComponentTag.java:527)
at com.sun.faces.taglib.html_basic.PanelGridTag.doEndTag(PanelGridTag.java:460)
at org.apache.jsp.index_jsp._jspx_meth_h_005fpanelGrid_005f0(index_jsp.java:290)
at org.apache.jsp.index_jsp._jspx_meth_h_005fform_005f0(index_jsp.java:243)
at org.apache.jsp.index_jsp._jspx_meth_f_005fview_005f0(index_jsp.java:207)
at org.apache.jsp.index_jsp._jspService(index_jsp.java:168)
at org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:70)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:803)
at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:393)
at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:320)
at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:266)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:803)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.apache.catalina.core.ApplicationDispatcher.invoke(ApplicationDispatcher.java:654)
at org.apache.catalina.core.ApplicationDispatcher.processRequest(ApplicationDispatcher.java:445)
at org.apache.catalina.core.ApplicationDispatcher.doForward(ApplicationDispatcher.java:379)
at org.apache.catalina.core.ApplicationDispatcher.forward(ApplicationDispatcher.java:292)
at com.sun.faces.context.ExternalContextImpl.dispatch(ExternalContextImpl.java:346)
at com.sun.faces.application.ViewHandlerImpl.renderView(ViewHandlerImpl.java:152)
at com.sun.faces.lifecycle.RenderResponsePhase.execute(RenderResponsePhase.java:107)
at com.sun.faces.lifecycle.LifecycleImpl.phase(LifecycleImpl.java:245)
at com.sun.faces.lifecycle.LifecycleImpl.render(LifecycleImpl.java:137)
at javax.faces.webapp.FacesServlet.service(FacesServlet.java:198)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at upload.UploadMultipartFilter.doFilter(UploadMultipartFilter.java:29)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:175)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:128)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:263)
at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:844)
at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:584)
at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:447)
at java.lang.Thread.run(Unknown Source)
Decode problem
2007-11-07 04:48:22 fridahenricson
[Reply | View]
Hi,
I´ve read that some of you have had this problem "The problem that I am noticing is that the Ajax requests are not being passed to the FileUploadRenderer.Decode() method for processing. Decode() only gets called once, for the first "normal decoding request" and never to process the file progress request events. " Has anyone any solution?
This worked for me then I used Eclipse 3.2 and tomcat 5.0, but now I´ve upgraded to Eclipse 3.3(europa) and tomcat 6.0 with some new jar-files. This is the jar-files i use in my project now:
ajax4jsf.jar
commons-beanutils.jar
commons-codec-1.3.jar
commons-collections-3.1.jar
commons-digester-1.6.jar
commons-el-1.0.jar
commons-fileupload-1.1.jar
commons-io-1.1.jar
commons-lang-2.1.jar
commons-logging-1.0.4.jar
commons-validator-1.3.1.jar
jstl-1.1.0.jar
myfaces-api-1.1.5.jar
myfaces-impl-1.1.5.jar
oro-2.0.8.jar
oscache-2.3.2.jar
tomahawk-1.1.6.jar
Can anyone say what might be wrong?
//Frida
Decode problem
2008-02-02 03:17:13 mceccarellitnx
[Reply | View]
I havethe same problem... have you resolved ?
my pants are on fire!
2007-10-11 12:00:58 vajav
[Reply | View]