You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@cxf.apache.org by allam-di14 <al...@hotmail.com> on 2014/03/04 14:41:41 UTC

How to configure CXF for a single JAXBContext and for an automatic JAXBElement conversion?

Hello,

I would like to configure cxf in order to avoid:
- using @XmlSeeAlso annotation particularly to allow inheritance 
- using @XmlRootElement for marshalling/unmarsahlling.

In accordance with what I found in the cxf documentation and the cxd users
forum, I have to  :
- use a single JAXBContext 
- update an existing ObjectFactory with methods returning JAXBElements or
simply set an 'unmarshalFromJaxbElement' property for JAXB 

First, I am trying to do it for a SOAP web service at the client and the
server sides. 
In order to use a single JAXBContext, I did the following:
- I created a GlobalContext class:
public class GlobalContext {

	public static JAXBContext getJAXBContext(){
		try {
                        // the name of my package is "test"
			return JAXBContext.newInstance("test");
		 } catch (JAXBException e) {
			   e.printStackTrace();
		 }
		return null;
	   }
}

- I changed my beans.xml file as follows:
-- at the server
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:jaxws="http://cxf.apache.org/jaxws"
	xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd">
	<import resource="classpath:META-INF/cxf/cxf.xml" />
	<import resource="classpath:META-INF/cxf/cxf-extension-soap.xml" />
	<import resource="classpath:META-INF/cxf/cxf-servlet.xml" />
	<jaxws:endpoint xmlns:tns="http://test/" id="service"
		implementor="test.Service" wsdlLocation="wsdl/service.wsdl"
		endpointName="tns:ServicePort" serviceName="tns:ServiceService"
		address="/ServicePort">
		<jaxws:properties>
    	    <entry key="schema-validation-enabled" value="false" />
 	   </jaxws:properties>
		<jaxws:features>
			<bean class="org.apache.cxf.feature.LoggingFeature" />
		</jaxws:features>
	        <jaxws:dataBinding>
        	        <bean class="org.apache.cxf.jaxb.JAXBDataBinding" >
    			       <constructor-arg index="0" ref="globalContext"/>
			</bean>
    	        </jaxws:dataBinding> 
	</jaxws:endpoint>
	<bean id= "globalContext" class="test.GlobalContext"
factory-method="getJAXBContext"/>
</beans>

-- at the client
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:jaxws="http://cxf.apache.org/jaxws"
	xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd">
	
	<jaxws:client createdFromAPI="false">
    <jaxws:dataBinding>
        	<bean class="org.apache.cxf.jaxb.JAXBDataBinding" >
    			<constructor-arg index="0" ref="globalContext"/>
			</bean>
    	</jaxws:dataBinding>
	</jaxws:client>
	<bean id= "globalContext" class="test.GlobalContext"
factory-method="getJAXBContext"/>
</beans>

and the web.xml file at the client is:
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID"
version="2.5">
  <display-name>SOAP-test2Client</display-name>

  <context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>WEB-INF/cxf-beans.xml</param-value>
  </context-param>

</web-app>


In my "test" package, I have two classes A and B, B inherits A, and a
service operation void op(A a).
I don't have any annotations in these classes at the client or the server
sides.
If my above cxf configuration is correct, it should run as if I do the
following code in JAXB:

try {
			 JAXBContext jc = JAXBContext.newInstance("test");
                       // for marshalling a b instance used to call "op" at
the client side
		       Marshaller marshaller = jc.createMarshaller();	        
		        
		        B b = new B();
		        b.setX("hello");
		        b.setY(32);
		        Op op = new Op();
		        op.setArg0(b);
		        JAXBElement<Op> op2 = new JAXBElement<Op>(new
QName("http://test/", "op"), Op.class, op);
		        marshaller.marshal(op2, System.out);

                         // for unmarshalling at the server side
		        File out = new File("src/test/output.xml");
				marshaller.marshal(op2, out);
				Unmarshaller unmarshaller = jc.createUnmarshaller();
				StreamSource xml2 = new StreamSource("src/test/output.xml");
				JAXBElement<Op> op3 =  unmarshaller.unmarshal(xml2, Op.class);
		         
		        System.out.println( op3.getValue().getArg0());
		          
		} catch (JAXBException e) {
			e.printStackTrace();
		}
       

However, tests shows that its is not correct.
For instance, I have the following exception when I  run my client with my
spring configuration:
Mar 4, 2014 2:27:52 PM
org.apache.cxf.service.factory.ReflectionServiceFactoryBean
buildServiceFromWSDL
INFO: Creating Service {http://test/}ServiceService from WSDL:
http://localhost:8080/SOAP-test2/services/ServicePort?wsdl
Exception in thread "main" javax.xml.ws.WebServiceException:
org.apache.cxf.service.factory.ServiceConstructionException
	at org.apache.cxf.jaxws.ServiceImpl.getPort(ServiceImpl.java:347)
	at org.apache.cxf.jaxws.ServiceImpl.getPort(ServiceImpl.java:336)
	at javax.xml.ws.Service.getPort(Service.java:92)
	at test.ServiceService.getServicePort(ServiceService.java:58)
	at
test.ServiceInterface_ServicePort_Client.main(ServiceInterface_ServicePort_Client.java:50)
Caused by: org.apache.cxf.service.factory.ServiceConstructionException
	at org.apache.cxf.jaxb.JAXBDataBinding.initialize(JAXBDataBinding.java:341)
	at
org.apache.cxf.service.factory.AbstractServiceFactoryBean.initializeDataBindings(AbstractServiceFactoryBean.java:86)
	at
org.apache.cxf.service.factory.ReflectionServiceFactoryBean.buildServiceFromWSDL(ReflectionServiceFactoryBean.java:446)
	at
org.apache.cxf.service.factory.ReflectionServiceFactoryBean.initializeServiceModel(ReflectionServiceFactoryBean.java:548)
	at
org.apache.cxf.service.factory.ReflectionServiceFactoryBean.create(ReflectionServiceFactoryBean.java:265)
	at
org.apache.cxf.jaxws.support.JaxWsServiceFactoryBean.create(JaxWsServiceFactoryBean.java:215)
	at
org.apache.cxf.frontend.AbstractWSDLBasedEndpointFactory.createEndpoint(AbstractWSDLBasedEndpointFactory.java:102)
	at
org.apache.cxf.frontend.ClientFactoryBean.create(ClientFactoryBean.java:91)
	at
org.apache.cxf.frontend.ClientProxyFactoryBean.create(ClientProxyFactoryBean.java:157)
	at
org.apache.cxf.jaxws.JaxWsProxyFactoryBean.create(JaxWsProxyFactoryBean.java:142)
	at org.apache.cxf.jaxws.ServiceImpl.createPort(ServiceImpl.java:478)
	at org.apache.cxf.jaxws.ServiceImpl.getPort(ServiceImpl.java:345)
	... 4 more
Caused by: com.sun.xml.bind.v2.runtime.IllegalAnnotationsException: 2 counts
of IllegalAnnotationExceptions
Two classes have the same XML type name "{http://test/}op". Use
@XmlType.name and @XmlType.namespace to assign different names to them.
	this problem is related to the following location:
		at test.jaxws_asm.Op
	this problem is related to the following location:
		at test.Op
		at public javax.xml.bind.JAXBElement test.ObjectFactory.createOp(test.Op)
		at test.ObjectFactory
Two classes have the same XML type name "{http://test/}opResponse". Use
@XmlType.name and @XmlType.namespace to assign different names to them.
	this problem is related to the following location:
		at test.jaxws_asm.OpResponse
	this problem is related to the following location:
		at test.OpResponse
		at public test.OpResponse test.ObjectFactory.createOpResponse()
		at test.ObjectFactory

	at
com.sun.xml.bind.v2.runtime.IllegalAnnotationsException$Builder.check(IllegalAnnotationsException.java:106)
	at
com.sun.xml.bind.v2.runtime.JAXBContextImpl.getTypeInfoSet(JAXBContextImpl.java:471)
	at
com.sun.xml.bind.v2.runtime.JAXBContextImpl.<init>(JAXBContextImpl.java:303)
	at
com.sun.xml.bind.v2.runtime.JAXBContextImpl.<init>(JAXBContextImpl.java:142)
	at
com.sun.xml.bind.v2.runtime.JAXBContextImpl$JAXBContextBuilder.build(JAXBContextImpl.java:1174)
	at
com.sun.xml.bind.v2.ContextFactory.createContext(ContextFactory.java:162)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
	at
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
	at java.lang.reflect.Method.invoke(Method.java:597)
	at javax.xml.bind.ContextFinder.newInstance(ContextFinder.java:202)
	at javax.xml.bind.ContextFinder.find(ContextFinder.java:363)
	at javax.xml.bind.JAXBContext.newInstance(JAXBContext.java:574)
	at
org.apache.cxf.common.jaxb.JAXBContextCache$2.run(JAXBContextCache.java:329)
	at
org.apache.cxf.common.jaxb.JAXBContextCache$2.run(JAXBContextCache.java:327)
	at java.security.AccessController.doPrivileged(Native Method)
	at
org.apache.cxf.common.jaxb.JAXBContextCache.createContext(JAXBContextCache.java:327)
	at
org.apache.cxf.common.jaxb.JAXBContextCache.getCachedContextAndSchemas(JAXBContextCache.java:228)
	at
org.apache.cxf.jaxb.JAXBDataBinding.createJAXBContextAndSchemas(JAXBDataBinding.java:482)
	at org.apache.cxf.jaxb.JAXBDataBinding.initialize(JAXBDataBinding.java:339)
	... 15 more
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

Even if I use a normal client, generated from the service WSDL file (which
contains all necessary annotations ), I have the following error at the
server when the client calls to void op(A a with a B instance:
ID: 8
Address: http://localhost:8080/SOAP-test2/services/ServicePort
Encoding: UTF-8
Http-Method: POST
Content-Type: text/xml; charset=UTF-8
Headers: {Accept=[*/*], cache-control=[no-cache], connection=[keep-alive],
Content-Length=[258], content-type=[text/xml; charset=UTF-8],
host=[localhost:8080], pragma=[no-cache], SOAPAction=[""],
user-agent=[Apache CXF 2.7.10]}
Payload: <soap:Envelope
xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"><soap:Body><ns2:op
xmlns:ns2="http://test/"><arg0
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:type="ns2:b"><x>salut</x><y>2014</y></arg0></ns2:op></soap:Body></soap:Envelope>
--------------------------------------
Mar 4, 2014 2:37:51 PM org.apache.cxf.phase.PhaseInterceptorChain
doDefaultLogging
WARNING: Interceptor for {http://test/}ServiceService#{http://test/}op has
thrown exception, unwinding now
org.apache.cxf.interceptor.Fault: Unmarshalling Error: unrecognized type
name: {http://test/}b. Did you mean b? 
	at
org.apache.cxf.jaxb.JAXBEncoderDecoder.unmarshall(JAXBEncoderDecoder.java:881)
	at
org.apache.cxf.jaxb.JAXBEncoderDecoder.unmarshall(JAXBEncoderDecoder.java:702)
	at org.apache.cxf.jaxb.io.DataReaderImpl.read(DataReaderImpl.java:160)
	at
org.apache.cxf.interceptor.DocLiteralInInterceptor.handleMessage(DocLiteralInInterceptor.java:107)
	at
org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:272)
	at
org.apache.cxf.transport.ChainInitiationObserver.onMessage(ChainInitiationObserver.java:121)
	at
org.apache.cxf.transport.http.AbstractHTTPDestination.invoke(AbstractHTTPDestination.java:239)
	at
org.apache.cxf.transport.servlet.ServletController.invokeDestination(ServletController.java:248)
	at
org.apache.cxf.transport.servlet.ServletController.invoke(ServletController.java:222)
	at
org.apache.cxf.transport.servlet.ServletController.invoke(ServletController.java:153)
	at
org.apache.cxf.transport.servlet.CXFNonSpringServlet.invoke(CXFNonSpringServlet.java:167)
	at
org.apache.cxf.transport.servlet.AbstractHTTPServlet.handleRequest(AbstractHTTPServlet.java:286)
	at
org.apache.cxf.transport.servlet.AbstractHTTPServlet.doPost(AbstractHTTPServlet.java:206)
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:646)
	at
org.apache.cxf.transport.servlet.AbstractHTTPServlet.service(AbstractHTTPServlet.java:262)
	at
org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:303)
	at
org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
	at
org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:220)
	at
org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:122)
	at
org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:501)
	at
org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:170)
	at
org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:98)
	at
org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:950)
	at
org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:116)
	at
org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:408)
	at
org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1040)
	at
org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:607)
	at
org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:315)
	at
java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:895)
	at
java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:918)
	at java.lang.Thread.run(Thread.java:695)
Caused by: javax.xml.bind.UnmarshalException
 - with linked exception:
[javax.xml.bind.UnmarshalException: unrecognized type name: {http://test/}b.
Did you mean b?]
	at
com.sun.xml.bind.v2.runtime.unmarshaller.UnmarshallerImpl.handleStreamException(UnmarshallerImpl.java:435)
	at
com.sun.xml.bind.v2.runtime.unmarshaller.UnmarshallerImpl.unmarshal0(UnmarshallerImpl.java:372)
	at
com.sun.xml.bind.v2.runtime.unmarshaller.UnmarshallerImpl.unmarshal(UnmarshallerImpl.java:349)
	at
org.apache.cxf.jaxb.JAXBEncoderDecoder.doUnmarshal(JAXBEncoderDecoder.java:842)
	at
org.apache.cxf.jaxb.JAXBEncoderDecoder.access$100(JAXBEncoderDecoder.java:101)
	at
org.apache.cxf.jaxb.JAXBEncoderDecoder$2.run(JAXBEncoderDecoder.java:870)
	at java.security.AccessController.doPrivileged(Native Method)
	at
org.apache.cxf.jaxb.JAXBEncoderDecoder.unmarshall(JAXBEncoderDecoder.java:868)
	... 30 more
%%%%%%%%%%%%%%%%%%%%%%%%



What I am missing exactly in my configuration?
It seems that my ObjectFactory class does not work as it should be.
Maybe it would be better to set 'unmarshalFromJaxbElement" to true in my
cxf-beans.xml file.
But how to do it?
Maybe also my spring configuration is not correct at the client. 
How to correct it and How to do the same thing in a Java code, without
spring?

Here is my ObjectFactory class:
@XmlRegistry
public class ObjectFactory {

    private final static QName _A_QNAME = new QName("http://test/", "a");
    private final static QName _OpResponse_QNAME = new QName("http://test/",
"opResponse");
    private final static QName _B_QNAME = new QName("http://test/", "b");
    private final static QName _Op_QNAME = new QName("http://test/", "op");

    /**
     * Create a new ObjectFactory that can be used to create new instances
of schema derived classes for package: test
     * 
     */
    public ObjectFactory() {
    }

    /**
     * Create an instance of {@link Op }
     * 
     */
    public Op createOp() {
        return new Op();
    }

    /**
     * Create an instance of {@link B }
     * 
     */
    public B createB() {
        return new B();
    }

    /**
     * Create an instance of {@link OpResponse }
     * 
     */
    public OpResponse createOpResponse() {
        return new OpResponse();
    }

    /**
     * Create an instance of {@link A }
     * 
     */
    public A createA() {
        return new A();
    }

    /**
     * Create an instance of {@link JAXBElement }{@code <}{@link A }{@code
>}}
     * 
     */
    @XmlElementDecl(namespace = "http://test/", name = "a")
    public JAXBElement  createA(A value) {
        return new JAXBElement (_A_QNAME, A.class, null, value);
    }

    /**
     * Create an instance of {@link JAXBElement }{@code <}{@link OpResponse
}{@code >}}
     * 
     */
    @XmlElementDecl(namespace = "http://test/", name = "opResponse")
    public JAXBElement<OpResponse> createOpResponse(OpResponse value) {
        return new JAXBElement<OpResponse>(_OpResponse_QNAME,
OpResponse.class, null, value);
    }

    /**
     * Create an instance of {@link JAXBElement }{@code <}{@link B }{@code
>}}
     * 
     */
    @XmlElementDecl(namespace = "http://test/", name = "b")
    public JAXBElement createB(B value) {
        return new JAXBElement(_B_QNAME, B.class, null, value);
    }

    /**
     * Create an instance of {@link JAXBElement }{@code <}{@link Op }{@code
>}}
     * 
     */
    @XmlElementDecl(namespace = "http://test/", name = "op")
    public JAXBElement<Op> createOp(Op value) {
        return new JAXBElement<Op>(_Op_QNAME, Op.class, null, value);
    }

}

Kind regards,
Diana 





--
View this message in context: http://cxf.547215.n5.nabble.com/How-to-configure-CXF-for-a-single-JAXBContext-and-for-an-automatic-JAXBElement-conversion-tp5740782.html
Sent from the cxf-user mailing list archive at Nabble.com.

Re: How to configure CXF for a single JAXBContext and for an automatic JAXBElement conversion?

Posted by allam-di14 <al...@hotmail.com>.
Hi Daniel,

Yes my WSDL/schema defines the B type as an extension of A.
I think the problem is due to the JAXBContext instance at invoking the "op"
operation.
It should contain just A class and not the B class. That justifies why my
message is unmarshalled as 
an A instance.
Therefore, my global jaxb context does not work as it should be.
It seems that in cxf 2.7.10 version, a JAXBElement instance is computed by
default on classes without JAXB annotations. Because, when I remove the
globalContext spring configuration in my cxf-beans.xml file at the server
side, I get exactly the same results.
Maybe there is another way to force JAXB to use a global context which
defines all the classes in my package? Which must do the same as adding
@XmlSeeAlso annotation

Kind regards,
Diana




--
View this message in context: http://cxf.547215.n5.nabble.com/How-to-configure-CXF-for-a-single-JAXBContext-and-for-an-automatic-JAXBElement-conversion-tp5740782p5740813.html
Sent from the cxf-user mailing list archive at Nabble.com.

Re: How to configure CXF for a single JAXBContext and for an automatic JAXBElement conversion?

Posted by "allam-di14 [via CXF]" <ml...@n5.nabble.com>.
Hi Daniel,

Yes my WSDL/schema defines the B type as an extension of A.
I think the problem is due to the JAXBContext instance at invoking the "op"
operation.
It should contain just A class and not the B class. That justifies why my
message is unmarshalled as 
an A instance.
Therefore, my global jaxb context does not work as it should be.
It seems that in cxf 2.7.10 version, a JAXBElement instance is computed by
default on classes without JAXB annotations. Because, when I remove the
globalContext spring configuration in my cxf-beans.xml file at the server
side, I get exactly the same results.
Maybe there is another way to force JAXB to use a global context which
defines all the classes in my package? Which must do the same as adding
@XmlSeeAlso annotation

Kind regards,
Diana





______________________________________
If you reply to this email, your message will be added to the discussion below:
http://cxf.547215.n5.nabble.com/How-to-configure-CXF-for-a-single-JAXBContext-and-for-an-automatic-JAXBElement-conversion-tp5740782p5740813.html
This email was sent by allam-di14 (via Nabble)
To receive all replies by email, subscribe to this discussion: http://cxf.547215.n5.nabble.com/template/NamlServlet.jtp?macro=subscribe_by_code&node=5740782&code=dXNlcnNAY3hmLmFwYWNoZS5vcmd8NTc0MDc4MnwtMTA5NTcxOTE5Nw==

Re: How to configure CXF for a single JAXBContext and for an automatic JAXBElement conversion?

Posted by Daniel Kulp <dk...@apache.org>.
This all looks OK for sending the B instance.   Can you double check that on the service side it knows about the B.class via an XmlSeeAlso annotation or similar?   If you do a ?wsdl on the service address, does the resulting wsdl/schema define the B type as an extension of A?

Dan



On Mar 4, 2014, at 1:09 PM, allam-di14 <al...@hotmail.com> wrote:

> In the meantime, I have made some improvements to my code.
> 
> I resolved the issue at the client side: the problem is due to a space in
> front of "address" in my spring configuration file:
> address=" http://localhost:8080/SOAP-test2/services/ServicePort" 
> 
> For the other problems, it was due to the JAXB validator. To resolve it, I
> disabled the validator handler in my spring configuration file:
> <jaxws:properties>
>    	    <entry key="schema-validation-enabled" value="false" />
>    	    <entry key="set-jaxb-validation-event-handler" value="false" /> 
> </jaxws:properties>
> 
> 
> My question now is, before when I used @XmlSeeAlso(B.class) on top of Class
> A, the client was able to call op with a B instance and it corresponds to an
> op invocation with a B instance at the server.
> (to remind, my operation op is defined as follows: void op(A a) such that B
> inherits A)
> 
> Now, by using a single JAXBContext and JAXBElement conversions, if a client
> calls op with a B instance, that corresponds to an op invocation with an A
> instance at the server.
> 
> Is-there a way to keep the same instances at the client and the server
> sides?
> 
> I did the following test code separately in JAXB:
>                        JAXBContext jc = JAXBContext.newInstance("test");
> 			 Marshaller marshaller = jc.createMarshaller();	        
> 		        
> 		        B b = new B();
> 		        b.setX("hello");
> 		        b.setY(32);
> 		        Op op = new Op();
> 		        op.setArg0(b);
> 		        JAXBElement<Op> op2 = new JAXBElement<Op>(new
> QName("http://test/", "op"), Op.class, op);
> 		        marshaller.marshal(op2, System.out);
> 				
> 		        
> 		        File out = new File("src/test/output.xml");
> 				marshaller.marshal(op2, out);
> 				Unmarshaller unmarshaller = jc.createUnmarshaller();
> 				StreamSource xml2 = new StreamSource("src/test/output.xml");
> 				JAXBElement<Op> op3 =  unmarshaller.unmarshal(xml2, Op.class);
> 		         
> 		        System.out.println( op3.getValue().getArg0());
> %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
> the result of unmarshalling is an OP instance with a reference to a B
> instance.
> Thus, the issue is not from JAXB, but maybe from the way cxf calls the
> unmarshal method on the received xml.
> 
> Indeed, their is not a difference between the soap body created by cxf:
> <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
> 	<soap:Body>
> 		<ns2:op xmlns:ns2="http://test/">
> 			<arg0 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
> 				xsi:type="ns2:b">
> 				<x>salut</x>
> 				<y>2014</y>
> 			</arg0>
> 		</ns2:op>
> 	</soap:Body>
> </soap:Envelope>
> --------------------------------------
> 
> and the xml created by my JAXB test code:
> <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
> <ns2:op xmlns:ns2="http://test/">
> 	<arg0 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
> 		xsi:type="b">
> 		<x>hello</x>
> 		<y>32</y>
> 	</arg0>
> </ns2:op>
> 
> I am using cxf 2.7.10 version
> 
> Any help please?
> Kind regards, 
> Diana 
> 
> 
> 
> 
> 
> --
> View this message in context: http://cxf.547215.n5.nabble.com/How-to-configure-CXF-for-a-single-JAXBContext-and-for-an-automatic-JAXBElement-conversion-tp5740782p5740803.html
> Sent from the cxf-user mailing list archive at Nabble.com.

-- 
Daniel Kulp
dkulp@apache.org - http://dankulp.com/blog
Talend Community Coder - http://coders.talend.com


Re: How to configure CXF for a single JAXBContext and for an automatic JAXBElement conversion?

Posted by allam-di14 <al...@hotmail.com>.
In the meantime, I have made some improvements to my code.

I resolved the issue at the client side: the problem is due to a space in
front of "address" in my spring configuration file:
address=" http://localhost:8080/SOAP-test2/services/ServicePort" 

For the other problems, it was due to the JAXB validator. To resolve it, I
disabled the validator handler in my spring configuration file:
<jaxws:properties>
    	    <entry key="schema-validation-enabled" value="false" />
    	    <entry key="set-jaxb-validation-event-handler" value="false" /> 
</jaxws:properties>


My question now is, before when I used @XmlSeeAlso(B.class) on top of Class
A, the client was able to call op with a B instance and it corresponds to an
op invocation with a B instance at the server.
(to remind, my operation op is defined as follows: void op(A a) such that B
inherits A)

Now, by using a single JAXBContext and JAXBElement conversions, if a client
calls op with a B instance, that corresponds to an op invocation with an A
instance at the server.

Is-there a way to keep the same instances at the client and the server
sides?

I did the following test code separately in JAXB:
                        JAXBContext jc = JAXBContext.newInstance("test");
			 Marshaller marshaller = jc.createMarshaller();	        
		        
		        B b = new B();
		        b.setX("hello");
		        b.setY(32);
		        Op op = new Op();
		        op.setArg0(b);
		        JAXBElement<Op> op2 = new JAXBElement<Op>(new
QName("http://test/", "op"), Op.class, op);
		        marshaller.marshal(op2, System.out);
				
		        
		        File out = new File("src/test/output.xml");
				marshaller.marshal(op2, out);
				Unmarshaller unmarshaller = jc.createUnmarshaller();
				StreamSource xml2 = new StreamSource("src/test/output.xml");
				JAXBElement<Op> op3 =  unmarshaller.unmarshal(xml2, Op.class);
		         
		        System.out.println( op3.getValue().getArg0());
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
the result of unmarshalling is an OP instance with a reference to a B
instance.
Thus, the issue is not from JAXB, but maybe from the way cxf calls the
unmarshal method on the received xml.

Indeed, their is not a difference between the soap body created by cxf:
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
	<soap:Body>
		<ns2:op xmlns:ns2="http://test/">
			<arg0 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
				xsi:type="ns2:b">
				<x>salut</x>
				<y>2014</y>
			</arg0>
		</ns2:op>
	</soap:Body>
</soap:Envelope>
--------------------------------------

and the xml created by my JAXB test code:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<ns2:op xmlns:ns2="http://test/">
	<arg0 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
		xsi:type="b">
		<x>hello</x>
		<y>32</y>
	</arg0>
</ns2:op>

I am using cxf 2.7.10 version

Any help please?
Kind regards, 
Diana 





--
View this message in context: http://cxf.547215.n5.nabble.com/How-to-configure-CXF-for-a-single-JAXBContext-and-for-an-automatic-JAXBElement-conversion-tp5740782p5740803.html
Sent from the cxf-user mailing list archive at Nabble.com.

Re: How to configure CXF for a single JAXBContext and for an automatic JAXBElement conversion?

Posted by allam-di14 <al...@hotmail.com>.
just a small precision. I made previously a mistake for client configuration
with spring.
At the client side, I have the following cxf-beans.xml file:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:jaxws="http://cxf.apache.org/jaxws"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd">
 
    <jaxws:client id="client"
                  serviceClass="test.ServiceInterface"
                  address="
http://localhost:8080/SOAP-test2/services/ServicePort" >
                  
     	<jaxws:dataBinding>
        	<bean class="org.apache.cxf.jaxb.JAXBDataBinding" >
    			<constructor-arg index="0" ref="globalContext"/>
            </bean>
    	</jaxws:dataBinding>
   </jaxws:client>
   <bean id= "globalContext" class="test.GlobalContext"
factory-method="getJAXBContext"/>
</beans>


And my java code is:
ClassPathXmlApplicationContext context 
            = new ClassPathXmlApplicationContext(new String[]
{"test/cxf-beans.xml"});

            ServiceInterface client =
(ServiceInterface)context.getBean("client");
        

            System.out.println("calling op with an instance of Class A");
            test.A a = new test.A();
            a.setX("hello");
            client.op(a);
            
            System.out.println("calling op with an instance of Class B");
            test.B b = new test.B();
            b.setX("salut");
            b.setY(2014);
            client.op(b);


with this I got the following error:
Mar 4, 2014 5:14:44 PM
org.apache.cxf.service.factory.ReflectionServiceFactoryBean
buildServiceFromClass
INFO: Creating Service {http://test/}ServiceInterfaceService from class
test.ServiceInterface
calling op with an instance of Class A
Exception in thread "main" javax.xml.ws.soap.SOAPFaultException: Could not
find conduit initiator for address: 
http://localhost:8080/SOAP-test2/services/ServicePort and transport:
http://schemas.xmlsoap.org/soap/http
	at org.apache.cxf.jaxws.JaxWsClientProxy.invoke(JaxWsClientProxy.java:157)
	at com.sun.proxy.$Proxy30.op(Unknown Source)
	at
test.ServiceInterface_ServicePort_Client.main(ServiceInterface_ServicePort_Client.java:70)
Caused by: java.lang.RuntimeException: Could not find conduit initiator for
address:  http://localhost:8080/SOAP-test2/services/ServicePort and
transport: http://schemas.xmlsoap.org/soap/http
	at
org.apache.cxf.binding.soap.SoapTransportFactory.getConduit(SoapTransportFactory.java:236)
	at
org.apache.cxf.binding.soap.SoapTransportFactory.getConduit(SoapTransportFactory.java:245)
	at
org.apache.cxf.endpoint.AbstractConduitSelector.getSelectedConduit(AbstractConduitSelector.java:103)
	at
org.apache.cxf.endpoint.UpfrontConduitSelector.prepare(UpfrontConduitSelector.java:63)
	at
org.apache.cxf.endpoint.ClientImpl.prepareConduitSelector(ClientImpl.java:886)
	at org.apache.cxf.endpoint.ClientImpl.doInvoke(ClientImpl.java:560)
	at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:474)
	at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:377)
	at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:330)
	at org.apache.cxf.frontend.ClientProxy.invokeSync(ClientProxy.java:96)
	at org.apache.cxf.jaxws.JaxWsClientProxy.invoke(JaxWsClientProxy.java:135)
	... 2 more



seems maybe that my beans file is not well configured for my service
location maybe? 
But I can't see where is the problem


regards, 
Diana




--
View this message in context: http://cxf.547215.n5.nabble.com/How-to-configure-CXF-for-a-single-JAXBContext-and-for-an-automatic-JAXBElement-conversion-tp5740782p5740799.html
Sent from the cxf-user mailing list archive at Nabble.com.