Lilz
Lilz

Reputation: 4089

Apache Commons fileUpload problem in java servlet

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

Upvotes: 1

Views: 5025

Answers (10)

cwash
cwash

Reputation: 4245

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!

Upvotes: 1

Spyder
Spyder

Reputation: 1902

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.

Upvotes: 0

toolkit
toolkit

Reputation: 50287

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);

Upvotes: 2

Bert F
Bert F

Reputation: 87603

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.

Upvotes: 1

albogdano
albogdano

Reputation: 2850

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.

Upvotes: 0

akarnokd
akarnokd

Reputation: 70007

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?

Upvotes: 1

Andrzej Doyle
Andrzej Doyle

Reputation: 103837

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.

Upvotes: 2

dfa
dfa

Reputation: 116412

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>

Upvotes: 0

Brian Agnew
Brian Agnew

Reputation: 272407

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)

Upvotes: 0

Chris Gow
Chris Gow

Reputation: 7934

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)

Upvotes: -1

Related Questions