You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@cxf.apache.org by amichalec <an...@gmail.com> on 2009/09/08 01:31:11 UTC

WebClient fails to unmarshall

Hi guys and hello after long absence ;)

it's late night in my place so it my be source of my problem but I stuck for
good early this evening and I see no other way than ask for hints ;)

I have working JAXRS service returning properly XML resource (to web
browser) being marshalled JAXB-enriched POJO. Since I want to automate a bit
testing of server side, I jumped to WebClient and tried to unmarshal
transported data to the same POJO:

		WebClient wc = WebClient.create("http://localhost:8080");
		wc.path("properly/set/path").accept(MediaType.APPLICATION_XML_TYPE);
		JaxbEnrichedObject obj = wc.get(JaxbEnrichedObject.class);

where "JaxbEnrichedObject" is class used on server side.
To my surprise it failed even though it was almost taken straight from cxf
test cases. Result was more or less like this:

Exception in thread "main" javax.ws.rs.WebApplicationException:
javax.ws.rs.WebApplicationException
	at org.apache.cxf.jaxrs.client.WebClient.handleResponse(WebClient.java:550)
	at
org.apache.cxf.jaxrs.client.WebClient.doChainedInvocation(WebClient.java:536)
	at org.apache.cxf.jaxrs.client.WebClient.doInvoke(WebClient.java:510)
	at org.apache.cxf.jaxrs.client.WebClient.invoke(WebClient.java:286)
	at org.apache.cxf.jaxrs.client.WebClient.get(WebClient.java:314)
	at ... 
Caused by: javax.ws.rs.WebApplicationException
	at
org.apache.cxf.jaxrs.client.AbstractClient.readBody(AbstractClient.java:404)
	at org.apache.cxf.jaxrs.client.WebClient.handleResponse(WebClient.java:544)
	... 5 more

Debugging session revealed that NPE occurs meanwhile but is swallowed during
exception rethrowing -- NPE pops up in
JAXBElementProvider.unmarshalFromReader() when JAXB unmarshaller is called
for input stream. I do not think debugging JAXB help me answer my
question... so what am I missing here?

cheers,
andy.
-- 
View this message in context: http://www.nabble.com/WebClient-fails-to-unmarshall-tp25337879p25337879.html
Sent from the cxf-user mailing list archive at Nabble.com.


Re: WebClient fails to unmarshall

Posted by Sergey Beryozkin <se...@iona.com>.
> The IllegalArgumentException is coming directly out of CGLIB

from Java Proxy....


Sergey Beryozkin wrote:
> 
> Hi Andy
> 
> CXf does not ship CGLIB and I've updated the docs recently that a CGLIB
> lib has to be added in such cases.
> The IllegalArgumentException is coming directly out of CGLIB, but I've
> updated the catch block to check for the actual IllegalArgumentException 
> message and if it matches "'simple classname' is not an interface' then ';
> make sure CGLIB is on classpath' will be added... I will update the trunk
> later on as I'm a bit busy at the moment...
> 
>> After adding 'wc.accept("text/xml")' to webclient add used three-params
>> version of 'fromClient()' with 'inherit param from client' set to true, I
>> finally passed test
> 
> inherit headers parameter can indeed be handy when converting from web
> clients to proxies (or vice versa). But you can also modify the proxy
> headers if needed as follows :
> 
> WebClient client ...
> Book proxy = JaxrsClientFactory.fromClient(webClient);
> WebClient.client(proxy).accept("application/xml");
> 
> cheers, Sergey
> 
> 
> amichalec wrote:
>> 
>> Hi Sergey,
>> this test project is generated by maven using the only
>> "cxf-rt-frontend-jaxrs" dependency which apparently does not imply use of
>> cglib. Adding lib solved my issue... and just to make excuse ;) I neither
>> noticed that I am missing CGLIB nor exception message suggested this
>> (message like "X is not interface; for proxying classes make sure CGLIB
>> is on classpath" would be perfect).
>> 
>> After that I was still experiencing WebApplicationException with "406 not
>> acceptable" and log message like this: "No operation matching request
>> path /foo is found, ContentType : */*, Accept : application/xml". After
>> adding 'wc.accept("text/xml")' to webclient add used three-params version
>> of 'fromClient()' with 'inherit param from client' set to true, I finally
>> passed test... 
>> 
>> Good to know stuff is working fine ;) thanks for your support.
>> 
>> cheers,
>> andy.
>> 
>> 
> 
> 

-- 
View this message in context: http://www.nabble.com/WebClient-fails-to-unmarshall-tp25337879p25398470.html
Sent from the cxf-user mailing list archive at Nabble.com.


Re: WebClient fails to unmarshall

Posted by Sergey Beryozkin <se...@iona.com>.
Hi Andy

CXf does not ship CGLIB and I've updated the docs recently that a CGLIB lib
has to be added in such cases.
The IllegalArgumentException is coming directly out of CGLIB, but I've
updated the catch block to check for the actual IllegalArgumentException 
message and if it matches "'simple classname' is not an interface' then ';
make sure CGLIB is on classpath' will be added... I will update the trunk
later on as I'm a bit busy at the moment...

> After adding 'wc.accept("text/xml")' to webclient add used three-params
> version of 'fromClient()' with 'inherit param from client' set to true, I
> finally passed test

inherit headers parameter can indeed be handy when converting from web
clients to proxies (or vice versa). But you can also modify the proxy
headers if needed as follows :

WebClient client ...
Book proxy = JaxrsClientFactory.fromClient(webClient);
WebClient.client(proxy).accept("application/xml");

cheers, Sergey


amichalec wrote:
> 
> Hi Sergey,
> this test project is generated by maven using the only
> "cxf-rt-frontend-jaxrs" dependency which apparently does not imply use of
> cglib. Adding lib solved my issue... and just to make excuse ;) I neither
> noticed that I am missing CGLIB nor exception message suggested this
> (message like "X is not interface; for proxying classes make sure CGLIB is
> on classpath" would be perfect).
> 
> After that I was still experiencing WebApplicationException with "406 not
> acceptable" and log message like this: "No operation matching request path
> /foo is found, ContentType : */*, Accept : application/xml". After adding
> 'wc.accept("text/xml")' to webclient add used three-params version of
> 'fromClient()' with 'inherit param from client' set to true, I finally
> passed test... 
> 
> Good to know stuff is working fine ;) thanks for your support.
> 
> cheers,
> andy.
> 
> 

-- 
View this message in context: http://www.nabble.com/WebClient-fails-to-unmarshall-tp25337879p25398243.html
Sent from the cxf-user mailing list archive at Nabble.com.


Re: WebClient fails to unmarshall

Posted by amichalec <an...@gmail.com>.
Hi Sergey,
this test project is generated by maven using the only
"cxf-rt-frontend-jaxrs" dependency which apparently does not imply use of
cglib. Adding lib solved my issue... and just to make excuse ;) I neither
noticed that I am missing CGLIB nor exception message suggested this
(message like "X is not interface; for proxying classes make sure CGLIB is
on classpath" would be perfect).

After that I was still experiencing WebApplicationException with "406 not
acceptable" and log message like this: "No operation matching request path
/foo is found, ContentType : */*, Accept : application/xml". After adding
'wc.accept("text/xml")' to webclient add used three-params version of
'fromClient()' with 'inherit param from client' set to true, I finally
passed test... 

Good to know stuff is working fine ;) thanks for your support.

cheers,
andy.

-- 
View this message in context: http://www.nabble.com/WebClient-fails-to-unmarshall-tp25337879p25383574.html
Sent from the cxf-user mailing list archive at Nabble.com.


Re: WebClient fails to unmarshall

Posted by Sergey Beryozkin <se...@iona.com>.
ok, thanks for confirming the 2nd test now working...

3rd one failure : Even with a cglib-nodep-2.1_3.jar on the classpath ?

cheers, Sergey


amichalec wrote:
> 
> Ouch... I have solved that problem -- it was strictly JAXB problem that
> works very silently when trying to unmarshall to object that has only
> annotated getters :/ after moving annotation to class members it started
> to work correctly. So the only case here is very quite JAXB engine, which
> shoul yell on me that I am trying to work with badly annotated class.
> 
> Third test case however remains -- JAXRSClientFactory contract says that
> one can provide interface or implementation of service, but when
> implementation provided WebApplicationException occurs caused by
> JAXRSClientFactoryBean.createWithValues(Object...) line: 137 and its
> "java.lang.IllegalArgumentException: net.amichalec.wstest.JaxrsService is
> not an interface" 
> 
> sorry for that fuss with WebClient ;)
> cheers,
> andy.
> 

-- 
View this message in context: http://www.nabble.com/WebClient-fails-to-unmarshall-tp25337879p25344741.html
Sent from the cxf-user mailing list archive at Nabble.com.


Re: WebClient fails to unmarshall

Posted by amichalec <an...@gmail.com>.
Ouch... I have solved that problem -- it was strictly JAXB problem that works
very silently when trying to unmarshall to object that has only annotated
getters :/ after moving annotation to class members it started to work
correctly. So the only case here is very quite JAXB engine, which shoul yell
on me that I am trying to work with badly annotated class.

Third test case however remains -- JAXRSClientFactory contract says that one
can provide interface or implementation of service, but when implementation
provided WebApplicationException occurs caused by
JAXRSClientFactoryBean.createWithValues(Object...) line: 137 and its
"java.lang.IllegalArgumentException: net.amichalec.wstest.JaxrsService is
not an interface" 

sorry for that fuss with WebClient ;)
cheers,
andy.
-- 
View this message in context: http://www.nabble.com/WebClient-fails-to-unmarshall-tp25337879p25344475.html
Sent from the cxf-user mailing list archive at Nabble.com.


Re: WebClient fails to unmarshall

Posted by Sergey Beryozkin <se...@iona.com>.
Hi Andy

I'm nearly sure that the test will start working if you add the setters as
well...And may be remove @XmlElement method annotations...Can you try it and
let me know if it works ?

As far as the CGLIB-related test is concerned : I've updated the
2.2.4-SNAPSHOT client code recently to report a message and not to lose the
exception in such cases as well. Are you sure you have a cglib-nodep
dependency on the classpath ? 

cheers, Sergey



amichalec wrote:
> 
> Hi Sergey
> 
> 
> Sergey Beryozkin wrote:
>> 
>> So as far as the NPE is concerned, it's coming from the JAXB layer, which
>> is then rethrown by JAXBElementProvider, right ?
>> 
>> or is NPE originating from JAXBElementProvider.unmarshalFromReader() ?
>> 
> 
> It comes from JAXB layer, that's why I feel reluctant to dig deeper ;)
> 
> 
> Sergey Beryozkin wrote:
>> 
>> This function is called if an XMLStreamReader has been found on a
>> message...
>> More information is needed, perhaps you can post a sample
>> JaxbEnrichedObject class ? Or some test case ?
>> 
> 
> Find attached maven project uploaded with this email. In this simplified
> case I do not hit NPE in JAXB but silently WebClient returns unmarshalled
> object that is empty inside (nulls instead of fulfilled fields). 
> 
> 
> Find code snippets below:
> 
> -------------------------------
> public class JaxrsService {
> 	@GET
> 	@Path("/foo")
> 	@Produces( "text/xml" )
> 	public Foo fooXml() {
> 		return new Foo("barval", "bazval");
> 	}
> 
> 	@GET
> 	@Path("/foo")
> 	@Produces( "text/plain" )
> 	public String fooString() {
> 		return new Foo("barval", "bazval").toString();
> 	}
> }
> 
> -------------------------------
> @XmlRootElement
> public class Foo {
> 	private String bar;
> 	private String baz;
> ...
> 
> 	@XmlElement
> 	public String getBar() {
> 		return bar;
> 	}
> 
> 	@XmlElement
> 	public String getBaz() {
> 		return baz;
> 	}
> ...
> }
> 
> -------------------------------
> public class JaxrsServiceTest {
> 
> 	private static Server server = null;
> 
> 	@BeforeClass
> 	public static void beforeClass() throws Exception {
> 		server = new Server(6080);
> 		Context root = new Context(server, "/");
> 		ServletHolder servlet = new ServletHolder(
> 				new CXFNonSpringJaxrsServlet());
> 		servlet.setInitParameter("jaxrs.serviceClasses",
> 				"net.amichalec.wctest.JaxrsService");
> 		root.addServlet(servlet, "/");
> 		server.start();
> 	}
> 
> 	@AfterClass
> 	public static void afterClass() throws Exception {
> 		server.stop();
> 	}
> 	
> 	@Test
> 	// it proves webclient and server work fine
> 	public void testNoJaxb() {
> 		WebClient wc = WebClient.create("http://localhost:6080");
> 		wc.path("/foo").accept("text/plain");
> 		String foo = wc.get(String.class);
> 		TestCase.assertEquals(new JaxrsService().fooString(), foo);
> 	}
> 
> 	@Test
> 	// this time there is not NPE in unmarshalling but returned object
> 	// is empty (contain nulls)
> 	public void testJaxbFailing() {
> 		WebClient wc = WebClient.create("http://localhost:6080");
> 		wc.path("/foo").accept("text/xml");
> 		Foo foo = wc.get(Foo.class);
> 		TestCase.assertEquals(new JaxrsService().fooXml(), foo);
> 	}
> 
> 	@Test
> 	// even though fromClient() offers cls parameter as
> 	// "if not interface then a CGLIB proxy will be created"
> 	// WAE is thrown (swallowing real cause "class is not interface")
> 	public void testProxyFailing() {
> 		WebClient wc = WebClient.create("http://localhost:6080");
> 		JaxrsService proxy = JAXRSClientFactory.fromClient(wc,
> 				JaxrsService.class);
> 		JaxrsService local = new JaxrsService();
> 		TestCase.assertEquals(local.fooXml(), proxy.fooXml());
> 	}
> }
> 
>  http://www.nabble.com/file/p25343761/webclient-test.zip
> webclient-test.zip 
> 

-- 
View this message in context: http://www.nabble.com/WebClient-fails-to-unmarshall-tp25337879p25344274.html
Sent from the cxf-user mailing list archive at Nabble.com.


Re: WebClient fails to unmarshall

Posted by amichalec <an...@gmail.com>.
Hi Sergey


Sergey Beryozkin wrote:
> 
> So as far as the NPE is concerned, it's coming from the JAXB layer, which
> is then rethrown by JAXBElementProvider, right ?
> 
> or is NPE originating from JAXBElementProvider.unmarshalFromReader() ?
> 

It comes from JAXB layer, that's why I feel reluctant to dig deeper ;)


Sergey Beryozkin wrote:
> 
> This function is called if an XMLStreamReader has been found on a
> message...
> More information is needed, perhaps you can post a sample
> JaxbEnrichedObject class ? Or some test case ?
> 

Find attached maven project uploaded with this email. In this simplified
case I do not hit NPE in JAXB but silently WebClient returns unmarshalled
object that is empty inside (nulls instead of fulfilled fields). 


Find code snippets below:

-------------------------------
public class JaxrsService {
	@GET
	@Path("/foo")
	@Produces( "text/xml" )
	public Foo fooXml() {
		return new Foo("barval", "bazval");
	}

	@GET
	@Path("/foo")
	@Produces( "text/plain" )
	public String fooString() {
		return new Foo("barval", "bazval").toString();
	}
}

-------------------------------
@XmlRootElement
public class Foo {
	private String bar;
	private String baz;
...

	@XmlElement
	public String getBar() {
		return bar;
	}

	@XmlElement
	public String getBaz() {
		return baz;
	}
...
}

-------------------------------
public class JaxrsServiceTest {

	private static Server server = null;

	@BeforeClass
	public static void beforeClass() throws Exception {
		server = new Server(6080);
		Context root = new Context(server, "/");
		ServletHolder servlet = new ServletHolder(
				new CXFNonSpringJaxrsServlet());
		servlet.setInitParameter("jaxrs.serviceClasses",
				"net.amichalec.wctest.JaxrsService");
		root.addServlet(servlet, "/");
		server.start();
	}

	@AfterClass
	public static void afterClass() throws Exception {
		server.stop();
	}
	
	@Test
	// it proves webclient and server work fine
	public void testNoJaxb() {
		WebClient wc = WebClient.create("http://localhost:6080");
		wc.path("/foo").accept("text/plain");
		String foo = wc.get(String.class);
		TestCase.assertEquals(new JaxrsService().fooString(), foo);
	}

	@Test
	// this time there is not NPE in unmarshalling but returned object
	// is empty (contain nulls)
	public void testJaxbFailing() {
		WebClient wc = WebClient.create("http://localhost:6080");
		wc.path("/foo").accept("text/xml");
		Foo foo = wc.get(Foo.class);
		TestCase.assertEquals(new JaxrsService().fooXml(), foo);
	}

	@Test
	// even though fromClient() offers cls parameter as
	// "if not interface then a CGLIB proxy will be created"
	// WAE is thrown (swallowing real cause "class is not interface")
	public void testProxyFailing() {
		WebClient wc = WebClient.create("http://localhost:6080");
		JaxrsService proxy = JAXRSClientFactory.fromClient(wc,
				JaxrsService.class);
		JaxrsService local = new JaxrsService();
		TestCase.assertEquals(local.fooXml(), proxy.fooXml());
	}
}

http://www.nabble.com/file/p25343761/webclient-test.zip webclient-test.zip 
-- 
View this message in context: http://www.nabble.com/WebClient-fails-to-unmarshall-tp25337879p25343761.html
Sent from the cxf-user mailing list archive at Nabble.com.


Re: WebClient fails to unmarshall

Posted by Sergey Beryozkin <se...@iona.com>.
Hi Andy

> hello after long absence ;)

good to hear from you again :-)

Just yesterday I updated the client code for it not to lose the exception
caught during AbstractClient readBody/writeBody. I've obviously been guilty
of writing the code which swallows exceptions (hopefully non of that is left
now).

So as far as the NPE is concerned, it's coming from the JAXB layer, which is
then rethrown by JAXBElementProvider, right ?

or is NPE originating from JAXBElementProvider.unmarshalFromReader() ?

This function is called if an XMLStreamReader has been found on a message...
More information is needed, perhaps you can post a sample JaxbEnrichedObject
class ? Or some test case ?

cheers, Sergey
 

amichalec wrote:
> 
> Hi guys and hello after long absence ;)
> 
> it's late night in my place so it my be source of my problem but I stuck
> for good early this evening and I see no other way than ask for hints ;)
> 
> I have working JAXRS service returning properly XML resource (to web
> browser) being marshalled JAXB-enriched POJO. Since I want to automate a
> bit testing of server side, I jumped to WebClient and tried to unmarshal
> transported data to the same POJO:
> 
> 		WebClient wc = WebClient.create("http://localhost:8080");
> 		wc.path("properly/set/path").accept(MediaType.APPLICATION_XML_TYPE);
> 		JaxbEnrichedObject obj = wc.get(JaxbEnrichedObject.class);
> 
> where "JaxbEnrichedObject" is class used on server side.
> To my surprise it failed even though it was almost taken straight from cxf
> test cases. Result was more or less like this:
> 
> Exception in thread "main" javax.ws.rs.WebApplicationException:
> javax.ws.rs.WebApplicationException
> 	at
> org.apache.cxf.jaxrs.client.WebClient.handleResponse(WebClient.java:550)
> 	at
> org.apache.cxf.jaxrs.client.WebClient.doChainedInvocation(WebClient.java:536)
> 	at org.apache.cxf.jaxrs.client.WebClient.doInvoke(WebClient.java:510)
> 	at org.apache.cxf.jaxrs.client.WebClient.invoke(WebClient.java:286)
> 	at org.apache.cxf.jaxrs.client.WebClient.get(WebClient.java:314)
> 	at ... 
> Caused by: javax.ws.rs.WebApplicationException
> 	at
> org.apache.cxf.jaxrs.client.AbstractClient.readBody(AbstractClient.java:404)
> 	at
> org.apache.cxf.jaxrs.client.WebClient.handleResponse(WebClient.java:544)
> 	... 5 more
> 
> Debugging session revealed that NPE occurs meanwhile but is swallowed
> during exception rethrowing -- NPE pops up in
> JAXBElementProvider.unmarshalFromReader() when JAXB unmarshaller is called
> for input stream. I do not think debugging JAXB help me answer my
> question... so what am I missing here?
> 
> cheers,
> andy.
> 

-- 
View this message in context: http://www.nabble.com/WebClient-fails-to-unmarshall-tp25337879p25342860.html
Sent from the cxf-user mailing list archive at Nabble.com.