You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@cxf.apache.org by NCorbet <Ne...@gmail.com> on 2013/06/18 15:15:04 UTC

Dosgi 1.4 JSONProvider not deserializing collections. Possible defect?

Hello all,

I am back again. After getting my restful services to migrate from 1.3 to
1.4, my problems now lie on the client side. I am using the following
service and POJO:

@Path("/report")
public interface ReportService {

        @GET
	@Path("/list")
	@Produces(MediaType.APPLICATION_JSON)
	public List<ReportDefinition> findAllReports();

}

@XmlRootElement
public class ReportDefinition implements Serializable{	
	private static final long serialVersionUID = 3244207063649073532L;
	
	private String reportName;
	private String reportDisplayName;
	
	private List<ParameterDefinition> parameterList;
	
	public ReportDefinition(){
	
	}
	
	public ReportDefinition(String reportName){
		super();
		this.reportName = reportName;
	}
	
	public ReportDefinition(String reportName, String reportDisplayName){
		super();
		this.reportName = reportName;
		this.reportDisplayName = reportDisplayName;
	}

	public String getReportName() {
		return reportName;
	}

	public void setReportName(String reportName) {
		this.reportName = reportName;
	}
	
	public String getReportDisplayName() {
		return reportDisplayName;
	}

	public void setReportDisplayName(String reportDisplayName) {
		this.reportDisplayName = reportDisplayName;
	}

	public List<ParameterDefinition> getParameterList() {
		return parameterList;
	}

	public void setParameterList(List<ParameterDefinition> parameterList) {
		this.parameterList = parameterList;
	}
	
	public void addParameterDefinition(ParameterDefinition
parameterDefinition){
		if(parameterList == null){
			parameterList = new ArrayList<ParameterDefinition>();
		}
		parameterList.add(parameterDefinition);
	}

	
}
Here is my Json Provider configuration:
<osgi:reference id="reportService"
		interface="org.syntech.reports.shared.services.ReportService" />

	<osgi:service
interface="org.syntech.reports.shared.services.ReportService">
		<osgi:service-properties>
			<entry key="service.exported.interfaces" value="*" />
			<entry key="service.exported.configs" value="org.apache.cxf.rs" />
			<entry key="service.exported.intents" value="HTTP" />

			<entry key="org.apache.cxf.rs.databinding" value="jaxb" />			
						
			
			<entry key="org.apache.cxf.rs.in.interceptors"
value="org.apache.cxf.interceptor.LoggingInInterceptor" />
			<entry key="org.apache.cxf.rs.out.interceptors"
value="org.apache.cxf.interceptor.LoggingOutInterceptor" />
			
			<entry key="org.apache.cxf.rs.provider">
				<array>
					 <ref bean="jsonProvider" />							
				</array>
			</entry>			
			<entry key="org.apache.cxf.rs.address"
value="${address-base-url}/ReportService" />
		</osgi:service-properties>
		<ref bean="reportService" />
	</osgi:service>	
	
	<bean id="jsonProvider"
class="org.apache.cxf.jaxrs.provider.json.JSONProvider" >		
		<property name="singleJaxbContext" value="true" />			
		<property name="marshallAsJaxbElement" value="true"/>
		<property name="unmarshallAsJaxbElement" value="true" />				
	</bean>	

The following json is produced ( and used to work fine in 1.3 ):

{
   "reportDefinition":
   [
       {
           "parameterList":
           [
               {
                   "defaultValue": "ZARC",
                   "multiValue": false,
                   "parameterName": "Site",
                   "parameterType":
"org.syntech.reports.shared.domain.StringParameter",
                   "required": true
               },
               {
                   "defaultValue": "%",
                   "multiValue": true,
                   "parameterName": "Tank",
                   "parameterType":
"org.syntech.reports.shared.domain.StringParameter",
                   "required": true
               }
           ],
           "reportDisplayName": "Title Unavailable",
           "reportName": "LastTankInfo"
       },
       {
           "parameterList":
           [
               {
                   "defaultValue": "%",
                   "multiValue": true,
                   "parameterName": "SiteID",
                   "parameterType":
"org.syntech.reports.shared.domain.StringParameter",
                   "required": true
               },
               {
                   "defaultValue": "#CCCCCC",
                   "multiValue": false,
                   "parameterName": "backGroundColor",
                   "parameterType":
"org.syntech.reports.shared.domain.StringParameter",
                   "required": true
               },
               {
                   "defaultValue": "2012-12-12",
                   "multiValue": false,
                   "parameterName": "EndTime",
                   "parameterType":
"org.syntech.reports.shared.domain.DateParameter",
                   "required": true
               },
               {
                   "defaultValue": "2010-12-12",
                   "multiValue": false,
                   "parameterName": "StartTime",
                   "parameterType":
"org.syntech.reports.shared.domain.DateParameter",
                   "required": true
               }
           ],
           "reportDisplayName": "Site Inventory",
           "reportName": "SiteInventory"
       }
   ]
}


Here is my client side configuration (worked in 1.3 ):

<jaxrs:client id="jaxrsReportService"		
		address="${jaxrs-syntech-reports.base-url}"
		serviceClass="org.syntech.reports.shared.services.ReportService"
		inheritHeaders="true">		
		<jaxrs:inInterceptors>
			<bean class="org.apache.cxf.interceptor.LoggingInInterceptor" />
		</jaxrs:inInterceptors>
		<jaxrs:outInterceptors>
			<bean class="org.apache.cxf.interceptor.LoggingOutInterceptor" />
		</jaxrs:outInterceptors>
		<jaxrs:properties>
       		<entry key="org.apache.cxf.output.buffering" value="false"/>
    	</jaxrs:properties>
		<jaxrs:providers>
			<ref bean="jsonProvider" />
		</jaxrs:providers>
</jaxrs:client>
	
<bean id="jsonProvider"
class="org.apache.cxf.jaxrs.provider.json.JSONProvider" >		
		<property name="singleJaxbContext" value="true" />				
		<property name="marshallAsJaxbElement" value="true"/>
		<property name="unmarshallAsJaxbElement" value="true" />				
</bean>	

When I debug the code, It fails when it hits the following code in
JSONProvider:

 if (isCollection) {
                response =
((CollectionWrapper)response).getCollectionOrArray(theType, type, 
                              
org.apache.cxf.jaxrs.utils.JAXBUtils.getAdapter(theGenericType, anns)); 
}

*isCollection* = true

*theType* = class org.syntech.reports.shared.domain.ReportDefinition

*type* = java.util.List

*theGenericType* = class org.syntech.reports.shared.domain.ReportDefinition

*anns* = [@javax.ws.rs.GET(), @javax.ws.rs.Path(value=/list),
@javax.ws.rs.Produces(value=[application/json])]

Where it fails: it tries to cast my ReportDefinition class to
org.apache.cxf.jaxrs.provider.AbstractJAXBProvider$CollectionWrapper

This doesnt seem right to me, shouldn't it try to cast the List to the
CollectionWrapper? 

Is there some more parameters I need to add to my server/client JSONProvider
configurations?

Thanks,
Neil



--
View this message in context: http://cxf.547215.n5.nabble.com/Dosgi-1-4-JSONProvider-not-deserializing-collections-Possible-defect-tp5729447.html
Sent from the cxf-user mailing list archive at Nabble.com.

Re: Dosgi 1.4 JSONProvider not deserializing collections. Possible defect?

Posted by NCorbet <Ne...@gmail.com>.
Thanks Sergey. I was debugging this.earlier and I came down the specific
difference in the code where the issue came up...then I had to step out.

After looking at the configuration item you posted, it occured to me that it
was missing from my original.config and I transposed it over to the client
side from the server side. So you are right, with that config it would not
work in 1.3 as well. Sorry for the mis-step. 

thanks again.



--
View this message in context: http://cxf.547215.n5.nabble.com/Dosgi-1-4-JSONProvider-not-deserializing-collections-Possible-defect-tp5729447p5729527.html
Sent from the cxf-user mailing list archive at Nabble.com.

Re: Dosgi 1.4 JSONProvider not deserializing collections. Possible defect?

Posted by Sergey Beryozkin <sb...@gmail.com>.
Hi

I've got this issue fixed, thanks for reporting it, to be honest I'm not 
seeing how it worked earlier :-), but may be I'm missing something

It should work for you now if on the client side you remove the 
"unmarshallAsJaxbElement" property, will work as expected after the release;

Sergey

On 18/06/13 18:59, NCorbet wrote:
> If I do the following JSONProvider works:
>
> @XmlRootElement
> public class SiteListWrapper implements Serializable{
>
> 	private static final long serialVersionUID = -7126992538125646051L;
> 	
> 	private List<Site> siteList;
> 	
> 	public SiteListWrapper(){
> 		
> 	}
> 	
> 	public SiteListWrapper(List<Site> siteList){
> 		super();
> 		this.siteList = siteList;
> 	}
>
> 	public List<Site> getSiteList() {
> 		return siteList;
> 	}
>
> 	public void setSiteList(List<Site> siteList) {
> 		this.siteList = siteList;
> 	}
> 	
> 	
> }
>
> This is not an ideal solution as it would cause a fair amount of
> refactoring, especially since it worked "out of the box" with CXF Dosgi 1.3.
>
> Neil
>
>
>
> --
> View this message in context: http://cxf.547215.n5.nabble.com/Dosgi-1-4-JSONProvider-not-deserializing-collections-Possible-defect-tp5729447p5729457.html
> Sent from the cxf-user mailing list archive at Nabble.com.
>


-- 
Sergey Beryozkin

Talend Community Coders
http://coders.talend.com/

Blog: http://sberyozkin.blogspot.com

Re: Dosgi 1.4 JSONProvider not deserializing collections. Possible defect?

Posted by NCorbet <Ne...@gmail.com>.
If I do the following JSONProvider works:

@XmlRootElement
public class SiteListWrapper implements Serializable{

	private static final long serialVersionUID = -7126992538125646051L;
	
	private List<Site> siteList;
	
	public SiteListWrapper(){
		
	}
	
	public SiteListWrapper(List<Site> siteList){
		super();
		this.siteList = siteList;
	}

	public List<Site> getSiteList() {
		return siteList;
	}

	public void setSiteList(List<Site> siteList) {
		this.siteList = siteList;
	}
	
	
}

This is not an ideal solution as it would cause a fair amount of
refactoring, especially since it worked "out of the box" with CXF Dosgi 1.3.

Neil



--
View this message in context: http://cxf.547215.n5.nabble.com/Dosgi-1-4-JSONProvider-not-deserializing-collections-Possible-defect-tp5729447p5729457.html
Sent from the cxf-user mailing list archive at Nabble.com.

Re: Dosgi 1.4 JSONProvider not deserializing collections. Possible defect?

Posted by NCorbet <Ne...@gmail.com>.
I am back to using Jettison on the server side. 


Neil



--
View this message in context: http://cxf.547215.n5.nabble.com/Dosgi-1-4-JSONProvider-not-deserializing-collections-Possible-defect-tp5729447p5729452.html
Sent from the cxf-user mailing list archive at Nabble.com.

Re: Dosgi 1.4 JSONProvider not deserializing collections. Possible defect?

Posted by Sergey Beryozkin <sb...@gmail.com>.
Hi

Do you actually have Jettison or Jackson on the server side ? I thought 
it was Jackson, right ?

Sergey


On 18/06/13 14:15, NCorbet wrote:
> Hello all,
>
> I am back again. After getting my restful services to migrate from 1.3 to
> 1.4, my problems now lie on the client side. I am using the following
> service and POJO:
>
> @Path("/report")
> public interface ReportService {
>
>          @GET
> 	@Path("/list")
> 	@Produces(MediaType.APPLICATION_JSON)
> 	public List<ReportDefinition> findAllReports();
>
> }
>
> @XmlRootElement
> public class ReportDefinition implements Serializable{	
> 	private static final long serialVersionUID = 3244207063649073532L;
> 	
> 	private String reportName;
> 	private String reportDisplayName;
> 	
> 	private List<ParameterDefinition> parameterList;
> 	
> 	public ReportDefinition(){
> 	
> 	}
> 	
> 	public ReportDefinition(String reportName){
> 		super();
> 		this.reportName = reportName;
> 	}
> 	
> 	public ReportDefinition(String reportName, String reportDisplayName){
> 		super();
> 		this.reportName = reportName;
> 		this.reportDisplayName = reportDisplayName;
> 	}
>
> 	public String getReportName() {
> 		return reportName;
> 	}
>
> 	public void setReportName(String reportName) {
> 		this.reportName = reportName;
> 	}
> 	
> 	public String getReportDisplayName() {
> 		return reportDisplayName;
> 	}
>
> 	public void setReportDisplayName(String reportDisplayName) {
> 		this.reportDisplayName = reportDisplayName;
> 	}
>
> 	public List<ParameterDefinition> getParameterList() {
> 		return parameterList;
> 	}
>
> 	public void setParameterList(List<ParameterDefinition> parameterList) {
> 		this.parameterList = parameterList;
> 	}
> 	
> 	public void addParameterDefinition(ParameterDefinition
> parameterDefinition){
> 		if(parameterList == null){
> 			parameterList = new ArrayList<ParameterDefinition>();
> 		}
> 		parameterList.add(parameterDefinition);
> 	}
>
> 	
> }
> Here is my Json Provider configuration:
> <osgi:reference id="reportService"
> 		interface="org.syntech.reports.shared.services.ReportService" />
>
> 	<osgi:service
> interface="org.syntech.reports.shared.services.ReportService">
> 		<osgi:service-properties>
> 			<entry key="service.exported.interfaces" value="*" />
> 			<entry key="service.exported.configs" value="org.apache.cxf.rs" />
> 			<entry key="service.exported.intents" value="HTTP" />
>
> 			<entry key="org.apache.cxf.rs.databinding" value="jaxb" />			
> 						
> 			
> 			<entry key="org.apache.cxf.rs.in.interceptors"
> value="org.apache.cxf.interceptor.LoggingInInterceptor" />
> 			<entry key="org.apache.cxf.rs.out.interceptors"
> value="org.apache.cxf.interceptor.LoggingOutInterceptor" />
> 			
> 			<entry key="org.apache.cxf.rs.provider">
> 				<array>
> 					 <ref bean="jsonProvider" />							
> 				</array>
> 			</entry>			
> 			<entry key="org.apache.cxf.rs.address"
> value="${address-base-url}/ReportService" />
> 		</osgi:service-properties>
> 		<ref bean="reportService" />
> 	</osgi:service>	
> 	
> 	<bean id="jsonProvider"
> class="org.apache.cxf.jaxrs.provider.json.JSONProvider" >		
> 		<property name="singleJaxbContext" value="true" />			
> 		<property name="marshallAsJaxbElement" value="true"/>
> 		<property name="unmarshallAsJaxbElement" value="true" />				
> 	</bean>	
>
> The following json is produced ( and used to work fine in 1.3 ):
>
> {
>     "reportDefinition":
>     [
>         {
>             "parameterList":
>             [
>                 {
>                     "defaultValue": "ZARC",
>                     "multiValue": false,
>                     "parameterName": "Site",
>                     "parameterType":
> "org.syntech.reports.shared.domain.StringParameter",
>                     "required": true
>                 },
>                 {
>                     "defaultValue": "%",
>                     "multiValue": true,
>                     "parameterName": "Tank",
>                     "parameterType":
> "org.syntech.reports.shared.domain.StringParameter",
>                     "required": true
>                 }
>             ],
>             "reportDisplayName": "Title Unavailable",
>             "reportName": "LastTankInfo"
>         },
>         {
>             "parameterList":
>             [
>                 {
>                     "defaultValue": "%",
>                     "multiValue": true,
>                     "parameterName": "SiteID",
>                     "parameterType":
> "org.syntech.reports.shared.domain.StringParameter",
>                     "required": true
>                 },
>                 {
>                     "defaultValue": "#CCCCCC",
>                     "multiValue": false,
>                     "parameterName": "backGroundColor",
>                     "parameterType":
> "org.syntech.reports.shared.domain.StringParameter",
>                     "required": true
>                 },
>                 {
>                     "defaultValue": "2012-12-12",
>                     "multiValue": false,
>                     "parameterName": "EndTime",
>                     "parameterType":
> "org.syntech.reports.shared.domain.DateParameter",
>                     "required": true
>                 },
>                 {
>                     "defaultValue": "2010-12-12",
>                     "multiValue": false,
>                     "parameterName": "StartTime",
>                     "parameterType":
> "org.syntech.reports.shared.domain.DateParameter",
>                     "required": true
>                 }
>             ],
>             "reportDisplayName": "Site Inventory",
>             "reportName": "SiteInventory"
>         }
>     ]
> }
>
>
> Here is my client side configuration (worked in 1.3 ):
>
> <jaxrs:client id="jaxrsReportService"		
> 		address="${jaxrs-syntech-reports.base-url}"
> 		serviceClass="org.syntech.reports.shared.services.ReportService"
> 		inheritHeaders="true">		
> 		<jaxrs:inInterceptors>
> 			<bean class="org.apache.cxf.interceptor.LoggingInInterceptor" />
> 		</jaxrs:inInterceptors>
> 		<jaxrs:outInterceptors>
> 			<bean class="org.apache.cxf.interceptor.LoggingOutInterceptor" />
> 		</jaxrs:outInterceptors>
> 		<jaxrs:properties>
>         		<entry key="org.apache.cxf.output.buffering" value="false"/>
>      	</jaxrs:properties>
> 		<jaxrs:providers>
> 			<ref bean="jsonProvider" />
> 		</jaxrs:providers>
> </jaxrs:client>
> 	
> <bean id="jsonProvider"
> class="org.apache.cxf.jaxrs.provider.json.JSONProvider" >		
> 		<property name="singleJaxbContext" value="true" />				
> 		<property name="marshallAsJaxbElement" value="true"/>
> 		<property name="unmarshallAsJaxbElement" value="true" />				
> </bean>	
>
> When I debug the code, It fails when it hits the following code in
> JSONProvider:
>
>   if (isCollection) {
>                  response =
> ((CollectionWrapper)response).getCollectionOrArray(theType, type,
>
> org.apache.cxf.jaxrs.utils.JAXBUtils.getAdapter(theGenericType, anns));
> }
>
> *isCollection* = true
>
> *theType* = class org.syntech.reports.shared.domain.ReportDefinition
>
> *type* = java.util.List
>
> *theGenericType* = class org.syntech.reports.shared.domain.ReportDefinition
>
> *anns* = [@javax.ws.rs.GET(), @javax.ws.rs.Path(value=/list),
> @javax.ws.rs.Produces(value=[application/json])]
>
> Where it fails: it tries to cast my ReportDefinition class to
> org.apache.cxf.jaxrs.provider.AbstractJAXBProvider$CollectionWrapper
>
> This doesnt seem right to me, shouldn't it try to cast the List to the
> CollectionWrapper?
>
> Is there some more parameters I need to add to my server/client JSONProvider
> configurations?
>
> Thanks,
> Neil
>
>
>
> --
> View this message in context: http://cxf.547215.n5.nabble.com/Dosgi-1-4-JSONProvider-not-deserializing-collections-Possible-defect-tp5729447.html
> Sent from the cxf-user mailing list archive at Nabble.com.
>


-- 
Sergey Beryozkin

Talend Community Coders
http://coders.talend.com/

Blog: http://sberyozkin.blogspot.com