users@jersey.java.net

Re: [Jersey] Re: ContainerException: Exception injecting parameters to Web resource method via NPE

From: Paul Sandoz <Paul.Sandoz_at_Sun.COM>
Date: Mon, 24 Nov 2008 11:54:18 +0100

Hi,

I think i know what the issue is, apologies for the long time working
it out, i was being dumb cause i forgot to include the Java mail
dependency, thus could not reproduce, doh!

I have committed a fix in the trunk.

As a work around you could have separate methods for each media type:

        @POST
        @Produces("text/html")
        @Consumes("application/x-www-form-urlencoded")
        public String doPost(@FormParam("xml") String xml) { ... }

        @POST
        @Produces("text/html")
        @Consumes("multipart/form-data")
        public String doPost(@FormParam("xml") String xml) { ... }

Note that when both media types are supported on the same method there
are some different constraints in force than if they are separate,
this is because it is hard to fully abstract the processing for the
overloaded use of FormParam. The urlencoded is string based, where as
form-data is binary based. I need to find time to document this
carefully... currently i am what is referred to as time bankrupt!

Paul.

On Nov 21, 2008, at 7:47 PM, Davis Ford wrote:

> I am still not quite out of the woods yet on this issue.
>
> I have the following:
>
> @POST
> @Produces("text/html")
> @Consumes({"application/x-www-form-urlencoded", "multipart/form-
> data"})
> public String doPost(@FormParam("xml") String xml) {
>
> and I am testing using HttpUnit. All my test cases pass fine if I
> send the 'xml' parameter, but I have one test that does not, and it
> causes the stack trace posted below:
>
> Using jersey-server 1.0.1-SNAPSHOT, and I did mvn refresh this
> morning.
>
> My test case in general does something like this:
>
> import com.meterware.httpunit.PostMethodWebRequest;
> import com.meterware.httpunit.WebConversation;
> import com.meterware.httpunit.WebResponse;
>
> PostMethodWebRequest req = new PostMethodWebRequest(URL);
> WebConversation wc = new WebConversation();
> WebResponse resp = wc.getResponse(req);
>
> In my other tests, I set the xml parameter in the req object like:
>
> req.setParameter("xml", StringUtil.readFileAsString(XML));
>
> Those tests pass as expected, but the test where I don't set the
> parameter generates a NPE. I have confirmed that the content-type
> that HttpUnit is sending is:
> {Content-Type=application/x-www-form-urlencoded}.
>
> com.sun.jersey.api.container.ContainerException: Exception injecting
> parameters to Web resource method
> at
> com.sun.jersey.server.impl.model.method.dispatch.FormDispatchProvider
> $FormParamInInvoker.getParams(FormDispatchProvider.java:99)
> at
> com.sun.jersey.server.impl.model.method.dispatch.FormDispatchProvider
> $TypeOutInvoker._dispatch(FormDispatchProvider.java:128)
> at
> com
> .sun
> .jersey
> .server
> .impl
> .model
> .method
> .dispatch
> .ResourceJavaMethodDispatcher
> .dispatch(ResourceJavaMethodDispatcher.java:67)
> at
> com
> .sun
> .jersey
> .server.impl.uri.rules.HttpMethodRule.accept(HttpMethodRule.java:124)
> at
> com
> .sun
> .jersey
> .server
> .impl.uri.rules.ResourceClassRule.accept(ResourceClassRule.java:71)
> at
> com
> .sun
> .jersey
> .server
> .impl.uri.rules.RightHandPathRule.accept(RightHandPathRule.java:111)
> at
> com
> .sun
> .jersey
> .server
> .impl
> .uri
> .rules.RootResourceClassesRule.accept(RootResourceClassesRule.java:63)
> at
> com
> .sun
> .jersey
> .server
> .impl
> .application
> .WebApplicationImpl._handleRequest(WebApplicationImpl.java:555)
> at
> com
> .sun
> .jersey
> .server
> .impl
> .application
> .WebApplicationImpl.handleRequest(WebApplicationImpl.java:514)
> at
> com
> .sun
> .jersey
> .server
> .impl
> .application
> .WebApplicationImpl.handleRequest(WebApplicationImpl.java:505)
> at
> com
> .sun
> .jersey
> .spi
> .container.servlet.ServletContainer.service(ServletContainer.java:349)
> at javax.servlet.http.HttpServlet.service(HttpServlet.java:820)
> at
> org.mortbay.jetty.servlet.ServletHolder.handle(ServletHolder.java:502)
> at
> org.mortbay.jetty.servlet.ServletHandler.handle(ServletHandler.java:
> 363)
> at
> org
> .mortbay.jetty.security.SecurityHandler.handle(SecurityHandler.java:
> 216)
> at
> org.mortbay.jetty.servlet.SessionHandler.handle(SessionHandler.java:
> 181)
> at
> org.mortbay.jetty.handler.ContextHandler.handle(ContextHandler.java:
> 766)
> at
> org.mortbay.jetty.webapp.WebAppContext.handle(WebAppContext.java:417)
> at
> org
> .mortbay
> .jetty
> .handler
> .ContextHandlerCollection.handle(ContextHandlerCollection.java:230)
> at
> org
> .mortbay
> .jetty.handler.HandlerCollection.handle(HandlerCollection.java:114)
> at
> org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:
> 152)
> at org.mortbay.jetty.Server.handle(Server.java:324)
> at
> org.mortbay.jetty.HttpConnection.handleRequest(HttpConnection.java:
> 534)
> at org.mortbay.jetty.HttpConnection
> $RequestHandler.headerComplete(HttpConnection.java:864)
> at org.mortbay.jetty.HttpParser.parseNext(HttpParser.java:533)
> at
> org.mortbay.jetty.HttpParser.parseAvailable(HttpParser.java:207)
> at
> org.mortbay.jetty.HttpConnection.handle(HttpConnection.java:403)
> at org.mortbay.jetty.bio.SocketConnector
> $Connection.run(SocketConnector.java:228)
> at org.mortbay.jetty.security.SslSocketConnector
> $SslConnection.run(SslSocketConnector.java:636)
> at org.mortbay.thread.QueuedThreadPool
> $PoolThread.run(QueuedThreadPool.java:522)
> Caused by: com.sun.jersey.api.container.ContainerException:
> java.lang.NullPointerException
> at
> com
> .sun
> .jersey
> .server.impl.model.method.dispatch.MultipartFormDispatchProvider
> $
> MultipartFormParamInjectable
> .getValue(MultipartFormDispatchProvider.java:180)
> at
> com.sun.jersey.server.impl.model.method.dispatch.FormDispatchProvider
> $FormParamInInvoker.getParams(FormDispatchProvider.java:93)
> ... 29 more
> Caused by: java.lang.NullPointerException
> at
> com
> .sun
> .jersey
> .server.impl.model.method.dispatch.MultipartFormDispatchProvider
> $
> MultipartFormParamInjectable
> .getAsForm(MultipartFormDispatchProvider.java:195)
> at
> com
> .sun
> .jersey
> .server.impl.model.method.dispatch.MultipartFormDispatchProvider
> $
> MultipartFormParamInjectable
> .getValue(MultipartFormDispatchProvider.java:175)
> ... 30 more
>
>
> On Thu, Nov 20, 2008 at 10:23 AM, Paul Sandoz <Paul.Sandoz_at_sun.com>
> wrote:
>>
>> On Nov 20, 2008, at 4:07 PM, Davis Ford wrote:
>>
>>> FYI, even though semantically this may not make sense in the
>>> traditional HTTP header sense, it achieves the catch-all I was
>>> looking
>>> for (if the POSTer is really sending Content-Type:application/xml or
>>> text/xml), and makes the NPE go away:
>>>
>>> @Consumes({"application/x-www-form-urlencoded", "application/xml",
>>> "text/xml"})
>>>
>>
>> How do you want to process the message if it is "application/xml" or
>> "text/xml" and what response do you want to produce?
>>
>> @FormParam only makes sense for form-based media types.
>>
>> You can have another method that catches anything else:
>>
>> @POST
>> // By default @Consumes("*")
>> public void anythingElse() {
>> }
>>
>> or you can let Jersey return a 415 client error.
>>
>>
>>> One other brief question...there are a lot of different jars in
>>> the maven
>>> repo:
>>>
>>> http://download.java.net/maven/2/com/sun/jersey/
>>>
>>> Is it documented somewhere what the different projects consist of?
>>> Granted you can use your intuition on the finely crafted naming
>>> strategy, but I was just curious for future reference.
>>>
>>> I am pulling in the 1.0.1-SNAPSHOT of jersey-core and jersey-server.
>>>
>>
>> https://jersey.dev.java.net/source/browse/*checkout*/jersey/trunk/jersey/dependencies.html
>>
>> Paul.
>>
>>> On Thu, Nov 20, 2008 at 9:42 AM, Paul Sandoz <Paul.Sandoz_at_sun.com>
>>> wrote:
>>>>
>>>> On Nov 20, 2008, at 3:15 PM, Davis Ford wrote:
>>>>
>>>>> Hi Paul,
>>>>>
>>>>> I can confirm the problem continues to exist for 1.0 and
>>>>> 1.0.1-SNAPSHOT. However, if I change the annotation as you were
>>>>> suspect of, the NPE goes away:
>>>>>
>>>>> @POST
>>>>> @Produces("text/html")
>>>>> // @Consumes({"application/x-www-form-urlencoded", "*/xml"})
>>>>> @Consumes("application/x-www-form-urlencoded")
>>>>>
>>>>
>>>> Also "*/xml" is a little odd, it is not really a valid wild card
>>>> media
>>>> type,
>>>> where as "text/*" is. You can only have "*", "foo/*" or "foo/bar".
>>>>
>>>>
>>>>> As to why I had this way...well, this is an integration between
>>>>> this
>>>>> organization I am contracting for and another outside party. I
>>>>> have
>>>>> tried to get confirmation from them on the HTTP header and what
>>>>> content-type will consist of. The only information I received was
>>>>> that it would be text/xml...although the content will come in a
>>>>> POST
>>>>> via a parameter like:
>>>>>
>>>>> xml=<?xml version="1.0"?><InboundPostRequest>etc.....
>>>>>
>>>>
>>>> Then the content type should still be
>>>> "application/x-www-form-urlencoded",
>>>> even if the value is of the xml parameter is a string that is an
>>>> XML
>>>> document.
>>>>
>>>> I think that is the issue in that the @FormParam only works with
>>>> "application/x-www-form-urlencoded" and "multipart/form-data", so
>>>> when
>>>> content is consumed that is of another media type confusion arises.
>>>>
>>>> Obviously i could improve the errors/warnings around all this.
>>>>
>>>>
>>>>> I would have assumed it would be x-www-form-urlencoded...but I
>>>>> have
>>>>> yet to do a real test with them. Therefore, I added the catch-all
>>>>> content-type for */xml in my unit tests, etc. In any event, NPE
>>>>> is
>>>>> not quite what I expected.
>>>>>
>>>>
>>>> Note that a 415 should be returned if the content type is not
>>>> supported
>>>> for
>>>> consumption.
>>>>
>>>>
>>>>> Thanks for your help. I have to just briefly say that building
>>>>> restful services via JAX-RS is truly a delight and I am really
>>>>> liking
>>>>> Jersey. Keep up the good work.
>>>>>
>>>>
>>>> Thanks!
>>>> Paul.
>>>>
>>>> ---------------------------------------------------------------------
>>>> To unsubscribe, e-mail: users-unsubscribe_at_jersey.dev.java.net
>>>> For additional commands, e-mail: users-help_at_jersey.dev.java.net
>>>>
>>>>
>>>
>>>
>>>
>>> --
>>> Zeno Consulting, Inc.
>>> http://www.zenoconsulting.biz
>>> 248.894.4922 phone
>>> 313.884.2977 fax
>>>
>>> ---------------------------------------------------------------------
>>> To unsubscribe, e-mail: users-unsubscribe_at_jersey.dev.java.net
>>> For additional commands, e-mail: users-help_at_jersey.dev.java.net
>>>
>>
>>
>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail: users-unsubscribe_at_jersey.dev.java.net
>> For additional commands, e-mail: users-help_at_jersey.dev.java.net
>>
>>
>
>
>
> --
> Zeno Consulting, Inc.
> http://www.zenoconsulting.biz
> 248.894.4922 phone
> 313.884.2977 fax
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe_at_jersey.dev.java.net
> For additional commands, e-mail: users-help_at_jersey.dev.java.net
>