views:

1122

answers:

10

Hi.

I tried doing this with Apache Commons FileUpload:

protected void processRequest(HttpServletRequest request, HttpServletResponse response)
throws ServletException {

    PrintWriter out = null;

    try {

        response.setContentType("text/html;charset=UTF-8");
        //MultipartFormDataRequest dataRequest = new MultipartFormDataRequest(request);
        //get uploaded files
        FileItemFactory factory = new DiskFileItemFactory();
        // Create a new file upload handler
        ServletFileUpload upload = new ServletFileUpload(factory);
        List files = null;
        try {
            files = upload.parseRequest(request);
        } catch (FileUploadException ex) {
            Logger.getLogger(ProcessUploadItem.class.getName()).log(Level.SEVERE, null, ex);
    }
}

and it failed at files = upload.parseRequest(request);

any pointers?

sorry and thank you :)

Sorry I hadn't included these:

The log message is null.
java.lang.NullPointerException
    at web.ProcessUploadItem.processRequest(ProcessUploadItem.java:156)
    at web.ProcessUploadItem.doPost(ProcessUploadItem.java:193)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:738)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:831)
    at org.apache.catalina.core.ApplicationFilterChain.servletService(ApplicationFilterChain.java:411)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:290)
    at org.apache.catalina.core.StandardContextValve.invokeInternal(StandardContextValve.java:271)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:202)
    at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:632)
    at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:577)
    at com.sun.enterprise.web.WebPipeline.invoke(WebPipeline.java:94)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:206)
    at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:632)
    at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:577)
    at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:571)
    at org.apache.catalina.core.ContainerBase.invoke(ContainerBase.java:1080)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:150)
    at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:632)
    at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:577)
    at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:571)
    at org.apache.catalina.core.ContainerBase.invoke(ContainerBase.java:1080)
    at org.apache.coyote.tomcat5.CoyoteAdapter.service(CoyoteAdapter.java:272)
    at com.sun.enterprise.web.connector.grizzly.DefaultProcessorTask.invokeAdapter(DefaultProcessorTask.java:637)
    at com.sun.enterprise.web.connector.grizzly.DefaultProcessorTask.doProcess(DefaultProcessorTask.java:568)
    at com.sun.enterprise.web.connector.grizzly.DefaultProcessorTask.process(DefaultProcessorTask.java:813)
    at com.sun.enterprise.web.connector.grizzly.DefaultReadTask.executeProcessorTask(DefaultReadTask.java:341)
    at com.sun.enterprise.web.connector.grizzly.DefaultReadTask.doTask(DefaultReadTask.java:263)
    at com.sun.enterprise.web.connector.grizzly.DefaultReadTask.doTask(DefaultReadTask.java:214)
    at com.sun.enterprise.web.connector.grizzly.TaskBase.run(TaskBase.java:265)
    at com.sun.enterprise.web.connector.grizzly.ssl.SSLWorkerThread.run(SSLWorkerThread.java:106)
java.lang.NullPointerException
    at web.ProcessUploadItem.processRequest(ProcessUploadItem.java:156)
    at web.ProcessUploadItem.doPost(ProcessUploadItem.java:193)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:738)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:831)
    at org.apache.catalina.core.ApplicationFilterChain.servletService(ApplicationFilterChain.java:411)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:290)
    at org.apache.catalina.core.StandardContextValve.invokeInternal(StandardContextValve.java:271)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:202)
    at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:632)
    at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:577)
    at com.sun.enterprise.web.WebPipeline.invoke(WebPipeline.java:94)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:206)
    at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:632)
    at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:577)
    at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:571)
    at org.apache.catalina.core.ContainerBase.invoke(ContainerBase.java:1080)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:150)
    at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:632)
    at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:577)
    at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:571)
    at org.apache.catalina.core.ContainerBase.invoke(ContainerBase.java:1080)
    at org.apache.coyote.tomcat5.CoyoteAdapter.service(CoyoteAdapter.java:272)
    at com.sun.enterprise.web.connector.grizzly.DefaultProcessorTask.invokeAdapter(DefaultProcessorTask.java:637)
    at com.sun.enterprise.web.connector.grizzly.DefaultProcessorTask.doProcess(DefaultProcessorTask.java:568)
    at com.sun.enterprise.web.connector.grizzly.DefaultProcessorTask.process(DefaultProcessorTask.java:813)
    at com.sun.enterprise.web.connector.grizzly.DefaultReadTask.executeProcessorTask(DefaultReadTask.java:341)
    at com.sun.enterprise.web.connector.grizzly.DefaultReadTask.doTask(DefaultReadTask.java:263)
    at com.sun.enterprise.web.connector.grizzly.DefaultReadTask.doTask(DefaultReadTask.java:214)
    at com.sun.enterprise.web.connector.grizzly.TaskBase.run(TaskBase.java:265)
    at com.sun.enterprise.web.connector.grizzly.ssl.SSLWorkerThread.run(SSLWorkerThread.java:106)

I'm using Glassfish

Thank you

A: 

You need to specify some more information when you say 'and it failed at files = upload.parseRequest(request)'. I'll take a stab at answering your question anyway.

Looking at the javadoc, you are creating an uninitialized DiskFileItemFactory object. You need to specify the directory where you want to store files. Either call setRepository() or create your factory by calling DiskFileItemFactory(int, File)

Chris Gow
I believe DiskFileItemFactory can be used without any further configuration, and it'll default to using the temp directory
Brian Agnew
Here (http://commons.apache.org/fileupload/using.html) it is used as Lily did.
Alberto Zaccagni
@Brian Agnew - Yes. You are correct. The javadoc for the no-args constructor is a little misleading: "Constructs an unconfigured instance of this class". Serves me right for not reading the whole thing.
Chris Gow
A: 

What does your form submission look like ? The above code looks good, and mirrors what I have.

Check your form submission is of the type 'multipart' thus:

boolean isMultipart = ServletFileUpload.isMultipartContent(request);

On the client side, you need to set the form encoding to multipart. See RFC1867.

Note also that parseRequest() will return null if the request data has been processed/read in any fashion prior to parseRequest() being called (see the Apache Commons File Upload FAQ)

Brian Agnew
tried that and it came true
Lily
A: 

The question is incomplet.

Which version of commons-upload are you using? Your form is using multipart/form-data MIME type as encoding type?

Here an example:

<form action="/uploadServlet" enctype="multipart/form-data" method="post">
  <input type="file" name="file" size="40">
  <input type="submit" value="Send">
</form>
dfa
out.println("<form action='ProcessUploadItem' method='post' enctype='multipart/form-data'>"); out.println("<h1>File upload</h1>"); out.println("Select a file:"); out.println("<input type='file' name='filename' />"); out.println("<br />"); out.println("<input type='submit' name='button' value='upload' />"); out.println("</form>");
Lily
+1  A: 

I would infer that upload is somehow null at that point. Are you sure that the source you gave and the compiled class file are the same version (e.g. the error line points to a different instruction)?

I guess you could debug your application with an IDE and create a breakpoint for NullPointerException.

Update: Could you please show what is after the inner catch block? What do you do with list? I guess you forgot that list might remain null if there is no file uploaded and you just start to iterate over it?

kd304
I am creating a breakpoint for NullPointerException...and in the case that I am trying I am actually uploading an actual file so it shouldn't be null :/
Lily
+2  A: 

From the stacktrace it's clear that one of the items that you dereference on line 156 of your class is null. Although we don't have line numbers in the snippet provided, it looks like this is only really possible on the upload.parseRequest line (which you yourself have also identified as the failing part).

Strangely enough it looks like this can only happen if upload is null - but from the code you have given this seems impossible since it's assigned a non-null value from a constructor just a few lines up and now changed since then.

If you can attach a debugger then stepping through your method and inspecting the object values would be a good idea. Otherwise, it might be worth putting a few println statements in just before that point to verify what objects are null and which are non-null.

Andrzej Doyle
A: 

When reading the documentation for DiskFileItemFactory I noticed that when a file is uploaded it is saved temporarily somewhere on the system and the default directory for that is the Temp directory as returned by System.getProperty("java.io.tmpdir"). Are you sure you have the permissions to write to this directory and if not maybe you can set a new repository/directory by calling factory.setRepository(java.io.File yourDir).

Not sure if this would help but it's just a suggestion.

Alex B
+1  A: 

I suspect that logger is throwing NullPointerException because shock "the log message is null".

Logger.getLogger(...).log(Level.SEVERE, >>>null<<<, ex);

One of the Log4J handlers (the Glassfish one) is handling the null message gracefully and printing the "The log message is null", but some other Log4J handler isn't handling the situation as well and throwing a NullPointerException.

This may explain why your stack traces are about a NullPointerException rather than about the FileUploadException that you are catching. I can't explain why the top of the NullPointerException stack trace is your code (ProcessUploadItem.java:156) other than the Throwable code that gets the stack frames can be fooled sometimes.

Regardless, I think the key to the problem, the FileUploadException ex, is getting lost as soon as the NullPointerException triggers, so there is no debug info on what's causing you to enter the catch block.

Pass a proper log message to the logger and/or the FileUploadException to print its message and stack trace to proceed further.

Bert F
Grrr, I see a logic error in my reasoning ... why isn't the Glassfish log handler printing the FileUploadException stack trace?
Bert F
if it were the null message, the NPE would come from inside the log() method, not the processRequest(). NPE could also come from the Logger.getLogger() call failing to return a logger
kd304
I agree with you, which is why I said in my answer: "I can't explain why the top of the NullPointerException stack trace is your code (ProcessUploadItem.java:156) ..." Something is missing - I can't reconcile that a log message does print ("The log message is null" is from line 324 of http://glassfish.sourcearchive.com/documentation/2ur2-b04/UniformLogFormatter_8java-source.html) indicating the .log() method is called successfully, that the catch is for FileUploadException but an NPE prints, and that the NPE stack trace ends in ProcessUploadItem.java code.
Bert F
+1  A: 

First - paste more!

The syntax you've pasted is invalid. You have a dangling try block with no catch or finally... I'd err on the side of pasting more information in here than less... Paste the entire method and put a comment on line 156 to indicate which it is.

What does the NPE mean?

As others have mentioned, the stacktrace is a null dereference from within your method somewhere. One of the objects you've tried to access something on (either a member variable or method using the . operator) is null. We can deduce this from your stack trace, but what doesn't make sense is the code you've pasted with it. We need more to be able to help figure it out.

Write a unit test to figure out the API calls

Also, I would write a unit test to learn how to work with this API before introducing the complexity of the servlet and logging APIs.

You can see how they tested the FileUpload API by looking at their Test Suite. You can reuse their MockHttpServletRequest (though this is really a fake object, not a mock object) for similar testing.

Note: you may want to browse back and look at versions of these files that match the version of your FileUpload jar.

Debugging pointers

To debug, here's what I'd do:

I'd breakpoint the first line in the method at the top of your stacktrace and take a look at the local watch variables as I step through the methods. Once you find and get rid of the NullPointerException, attach the FileUpload source and step into it to make sure you're actually entering that code if you happen to get a different FileUpload specific exception after that.

Good luck!

cwash
+2  A: 

The message The log message is null indicates it is complaining about the following:

log(Level.SEVERE, null, ex);

Better to use:

log(Level.SEVERE, "Failed to parse upload request", ex);
toolkit
A: 

Either upload is null on the processRequest line or you've miscounted the lines. You haven't posted the entire method, so we're all just guessing.

If the processRequest call is actually that close to the upload instantiation, my guess is you have some kind of post-processing. The code you are editing might not be the code you're compiling.

Spyder