You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@cxf.apache.org by Dennis Sosnoski <dm...@sosnoski.com> on 2010/04/30 02:00:32 UTC
JiBX databinding implementation
I'm curious how the JiBX databinding GSoC project is progressing...
anything to discuss yet?
JiBX is pretty flexible in how it reads and writes XML, with its own
org.jibx.runtime.IXMLReader and IXMLWriter interfaces used to decouple
from the details of the parser and writer. Implementations of these
interfaces are supplied for working with StAX XMLStreamReader and
XMLStreamWriter, and the existing Axis2 support for JiBX should be a
good guide for fitting the actual runtime hooks together.
Just to make sure I understand how this works, JAX-WS configuration can
be used with any type of org.apache.cxf.databinding.DataBinding
implementation, right? So someone wanting to use JiBX with a JAX-WS
frontend would just need to specify this using their preferred
configuration technique (such as cxf-client.xml on the client side).
Thanks,
- Dennis
Re: JiBX databinding implementation
Posted by Nilupa Bandara <ni...@gmail.com>.
Hi,
Thank you very much for this detailed reply. I've taken your points and will
update this mailing thread about the progress I've made and any issues I've
come across soon.
Thanks,
Nilupa
On Sat, May 29, 2010 at 5:26 AM, Dennis Sosnoski <dm...@sosnoski.com> wrote:
> Nilupa Bandara wrote:
>
>> Hello Everyone,
>>
>> The code that I've written so far is available at[1], [2] and it for
>> simple
>> data types. I've used the Axis2 JiBX implementation as guide and now I am
>> working on implementing the complex data type support.
>>
>>
>
> I haven't had a chance to look at this in any detail, but I suspect you may
> be going off track. The Axis2 support uses code generation of the actual
> stub code called by the client to access the server, and the message
> receiver code on the server side which calls the service method. The simple
> data type support comes in when unwrapping a request message from the WSDL
> to pass the child elements as method parameters.
>
> From what I understand of CXF's implementation it always uses a wrapper
> class that matches the actual request or response message element (which is
> the content of the SOAP Body element), and handles converting this into
> method parameters with shared logic. So you shouldn't need to work with the
> simple data types at all.
>
> What I'd think you would need to work on would be handling the actual JiBX
> conversions to and from the SOAP Body. I've tried taking a look at the
> XMLBeans support in CXF to see if I could get a handle on how this needs to
> be done, but I find the code hard to follow with the only comments brief
> one-liners on interface method definitions. So here's my take on how I think
> this should work, and perhaps Dan or someone else can help match this up
> with the CXF structure.
>
> To start with, you need to have some sort of configuration which tells you
> how to access the JiBX binding factory. JiBX is very flexible in how it
> handles bindings, including allowing multiple bindings of the same class to
> different XML representations. Each binding has an associated factory class
> used to work with that binding at runtime. You load a binding factory using
> the methods in org.jibx.runtime.BindingDirectory, which work with several
> variations of parameters:
>
> 1. by the binding name and base Java package in the binding
> 2. by the binding name and one of the classes mapped in that binding
> 3. by one of the classes mapped in the binding (if that class is only
> involved in one binding).
>
> You can pass a classloader to the first two variations, to specify where
> the classes can be found. If you don't supply a classloader, the
> BindingDirectory does its best to find things using the classloader which
> loaded the class you pass in (if using a class) or the classloader which
> loaded the BindingDirectory class (if using package name lookup). Binding
> factories are thread-safe and can be cached once you've found them.
>
> When handling input, you need to start with the XMLStreamReader positioned
> at the start tag of the message element (the child of the SOAP Body
> element). You create an unmarshalling context instance from the binding
> factory which you'll use for unmarshalling the data. This is an interface,
> but for your purposes you'll need to cast it to the actual implementation
> class org.jibx.runtime.impl.UnmarshallingContext and use the setDocument()
> method which takes an IXMLReader instance. You create the IXMLReader
> instance from your existing XMLStreamReader using the
> org.jibx.runtime.impl.StAXReaderWrapper constructor. You should be able to
> just call the unmarshalElement() method of the unmarshalling context and get
> back the unmarshalled instance.
>
> It looks like you've figured out much of this, but I wanted to spell it out
> to help you understand the sequence. From your stack trace it appears you're
> calling parseElementText(), which is definitely not what you want to use -
> this just returns text content for an element with no child elements.
>
> Handling output is a little different You first create a marshalling
> context, then a org.jibx.runtime.impl.StAXWriter using the constructor which
> takes an XMLStreamWriter (for the namespace URIs, just pass an array with
> the two required values listed in the method JavaDocs), and set the
> StAXWriter on the marshalling context. Then cast the object you're going to
> marshal to the org.jibx.runtime.IMarshallable interface (which is added to
> each mapped class by the JiBX binding compiler) and call the marshal()
> method defined by this interface.
>
> Hope this gets you further. Keep us posted on this list and I'll try to
> provide pointers whenever you run into problems.
>
> Once the basic JiBX runtime support is working we can discuss how to
> integrate JiBX code generation from schema, but I think the basic runtime
> support is the most important step.
>
> - Dennis
>
>
--
Nilupa Bandara
Re: JiBX databinding implementation
Posted by Dennis Sosnoski <dm...@sosnoski.com>.
Nilupa Bandara wrote:
> Hello Everyone,
>
> The code that I've written so far is available at[1], [2] and it for simple
> data types. I've used the Axis2 JiBX implementation as guide and now I am
> working on implementing the complex data type support.
>
I haven't had a chance to look at this in any detail, but I suspect you
may be going off track. The Axis2 support uses code generation of the
actual stub code called by the client to access the server, and the
message receiver code on the server side which calls the service method.
The simple data type support comes in when unwrapping a request message
from the WSDL to pass the child elements as method parameters.
From what I understand of CXF's implementation it always uses a wrapper
class that matches the actual request or response message element (which
is the content of the SOAP Body element), and handles converting this
into method parameters with shared logic. So you shouldn't need to work
with the simple data types at all.
What I'd think you would need to work on would be handling the actual
JiBX conversions to and from the SOAP Body. I've tried taking a look at
the XMLBeans support in CXF to see if I could get a handle on how this
needs to be done, but I find the code hard to follow with the only
comments brief one-liners on interface method definitions. So here's my
take on how I think this should work, and perhaps Dan or someone else
can help match this up with the CXF structure.
To start with, you need to have some sort of configuration which tells
you how to access the JiBX binding factory. JiBX is very flexible in how
it handles bindings, including allowing multiple bindings of the same
class to different XML representations. Each binding has an associated
factory class used to work with that binding at runtime. You load a
binding factory using the methods in org.jibx.runtime.BindingDirectory,
which work with several variations of parameters:
1. by the binding name and base Java package in the binding
2. by the binding name and one of the classes mapped in that binding
3. by one of the classes mapped in the binding (if that class is only
involved in one binding).
You can pass a classloader to the first two variations, to specify where
the classes can be found. If you don't supply a classloader, the
BindingDirectory does its best to find things using the classloader
which loaded the class you pass in (if using a class) or the classloader
which loaded the BindingDirectory class (if using package name lookup).
Binding factories are thread-safe and can be cached once you've found them.
When handling input, you need to start with the XMLStreamReader
positioned at the start tag of the message element (the child of the
SOAP Body element). You create an unmarshalling context instance from
the binding factory which you'll use for unmarshalling the data. This is
an interface, but for your purposes you'll need to cast it to the actual
implementation class org.jibx.runtime.impl.UnmarshallingContext and use
the setDocument() method which takes an IXMLReader instance. You create
the IXMLReader instance from your existing XMLStreamReader using the
org.jibx.runtime.impl.StAXReaderWrapper constructor. You should be able
to just call the unmarshalElement() method of the unmarshalling context
and get back the unmarshalled instance.
It looks like you've figured out much of this, but I wanted to spell it
out to help you understand the sequence. From your stack trace it
appears you're calling parseElementText(), which is definitely not what
you want to use - this just returns text content for an element with no
child elements.
Handling output is a little different You first create a marshalling
context, then a org.jibx.runtime.impl.StAXWriter using the constructor
which takes an XMLStreamWriter (for the namespace URIs, just pass an
array with the two required values listed in the method JavaDocs), and
set the StAXWriter on the marshalling context. Then cast the object
you're going to marshal to the org.jibx.runtime.IMarshallable interface
(which is added to each mapped class by the JiBX binding compiler) and
call the marshal() method defined by this interface.
Hope this gets you further. Keep us posted on this list and I'll try to
provide pointers whenever you run into problems.
Once the basic JiBX runtime support is working we can discuss how to
integrate JiBX code generation from schema, but I think the basic
runtime support is the most important step.
- Dennis
Re: JiBX databinding implementation
Posted by Daniel Kulp <dk...@apache.org>.
On Friday 21 May 2010 8:57:32 pm Nilupa Bandara wrote:
> Hello Everyone,
>
> The code that I've written so far is available at[1], [2] and it for simple
> data types. I've used the Axis2 JiBX implementation as guide and now I am
> working on implementing the complex data type support.
>
> However there seems to be an error when we present the XMLSteramReader
> obtained form CXF runtime to JiBX UnmashallingContext which needs work on
> process a part of an XML document not as a whole. However when we present
> an XMLStreamRead from which it can read the desired element as a whole
> document it seems to work.[4]. I suspect this is a bug in JiBX framework
> and I am willing to hear expert advice on this.
Not really sure what to suggest on this. I know with XMLBeans in JAX-RS, we
did have some issues if the XMLStreamReader wasn't positioned exactly where it
wanted to be. I think XMLBeans didn't want the start doc events or something
so had to make sure it was "next" beyond that. I would try fiddling with
the stream reader in your standalone "full document" case to see if you can
get it the same state as CXF presents it to see if that reproduces it and then
kind of reverse you changes to see what may be doable to fix how CXF calls
into JiBX.
Dan
>
> Any suggestions, advice and tips will be much appreciated !!
>
>
> Thanks & Regards,
> Nilupa
>
> [1] http://github.com/nilupa/cxf
>
> [2] http://github.com/nilupa/cxf/tree/trunk/rt/databinding/jibx/
>
> [3] Error output:
>
> ava.lang.ArrayIndexOutOfBoundsException: Attempt to peek past end of stack
> at org.jibx.runtime.IntStack.peek(IntStack.java:231)
> at org.jibx.runtime.IntStack.peek(IntStack.java:245)
> at
> org.jibx.runtime.impl.StAXReaderWrapper.endTag(StAXReaderWrapper.java:159)
> at
> org.jibx.runtime.impl.StAXReaderWrapper.nextToken(StAXReaderWrapper.java:18
> 2) at
> org.jibx.runtime.impl.UnmarshallingContext.accumulateText(UnmarshallingCont
> ext.java:840) at
> org.jibx.runtime.impl.UnmarshallingContext.parseContentText(UnmarshallingCo
> ntext.java:874) at
> org.jibx.runtime.impl.UnmarshallingContext.parseElementText(UnmarshallingCo
> ntext.java:936) at
> org.apache.xcf.jibx.JibxDataReader.read(JibxDataReader.java:57) at
> org.apache.xcf.jibx.JibxDataReader.read(JibxDataReader.java:1)
> at
> org.apache.cxf.interceptor.DocLiteralInInterceptor.getPara(DocLiteralInInte
> rceptor.java:251) at
> org.apache.cxf.interceptor.DocLiteralInInterceptor.handleMessage(DocLiteral
> InInterceptor.java:127) at
> org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChai
> n.java:243) at
> org.apache.cxf.transport.ChainInitiationObserver.onMessage(ChainInitiationO
> bserver.java:110) at
> org.apache.cxf.transport.http_jetty.JettyHTTPDestination.serviceRequest(Jet
> tyHTTPDestination.java:313) at
> org.apache.cxf.transport.http_jetty.JettyHTTPDestination.doService(JettyHTT
> PDestination.java:277) at
> org.apache.cxf.transport.http_jetty.JettyHTTPHandler.handle(JettyHTTPHandle
> r.java:70) at
> org.mortbay.jetty.handler.ContextHandler.handle(ContextHandler.java:765)
> at
> org.mortbay.jetty.handler.ContextHandlerCollection.handle(ContextHandlerCol
> lection.java:230) at
> org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:152)
> at org.mortbay.jetty.Server.handle(Server.java:326)
> at org.mortbay.jetty.HttpConnection.handleRequest(HttpConnection.java:536)
> at
> org.mortbay.jetty.HttpConnection$RequestHandler.content(HttpConnection.java
> :930) at org.mortbay.jetty.HttpParser.parseNext(HttpParser.java:747)
> at org.mortbay.jetty.HttpParser.parseAvailable(HttpParser.java:218)
> at org.mortbay.jetty.HttpConnection.handle(HttpConnection.java:405)
> at
> org.mortbay.io.nio.SelectChannelEndPoint.run(SelectChannelEndPoint.java:409
> ) at
> org.mortbay.thread.QueuedThreadPool$PoolThread.run(QueuedThreadPool.java:58
> 2)
>
> [4] Work around JibxDataReader.java : line 90
>
> try {
> reader =
> StaxUtils.createXMLStreamReader(StaxUtils.read(reader));
> } catch (Exception e) {
> throw new RuntimeException(e);
> }
>
>
>
>
> On Fri, Apr 30, 2010 at 11:30 AM, Nilupa Bandara
> <nilupa.manamperi@gmail.com
>
> > wrote:
> >
> > Hi,
> >
> > At the moment, I am running the sample Web services in debug mode just to
> > get a deeper understanding of how the cxf data
> >
> > binding architecture works at runtime. I am also planning to look at how
> >
> > its done for Axis2 and perhaps we might be able to reuse some of that
> > code there. As soon as I have something concrete, will post it to this
> > mailing list.
> >
> > Thanks & Best Regards,
> > Nilupa
> >
> > On Fri, Apr 30, 2010 at 2:00 AM, Dennis Sosnoski <dm...@sosnoski.com> wrote:
> >> I'm curious how the JiBX databinding GSoC project is progressing...
> >> anything to discuss yet?
> >>
> >> JiBX is pretty flexible in how it reads and writes XML, with its own
> >> org.jibx.runtime.IXMLReader and IXMLWriter interfaces used to decouple
> >> from the details of the parser and writer. Implementations of these
> >> interfaces are supplied for working with StAX XMLStreamReader and
> >> XMLStreamWriter, and the existing Axis2 support for JiBX should be a
> >> good guide for fitting the actual runtime hooks together.
> >>
> >> Just to make sure I understand how this works, JAX-WS configuration can
> >> be used with any type of org.apache.cxf.databinding.DataBinding
> >> implementation, right? So someone wanting to use JiBX with a JAX-WS
> >> frontend would just need to specify this using their preferred
> >> configuration technique (such as cxf-client.xml on the client side).
> >>
> >> Thanks,
> >>
> >> - Dennis
--
Daniel Kulp
dkulp@apache.org
http://dankulp.com/blog
Re: JiBX databinding implementation
Posted by Nilupa Bandara <ni...@gmail.com>.
Hello Everyone,
The code that I've written so far is available at[1], [2] and it for simple
data types. I've used the Axis2 JiBX implementation as guide and now I am
working on implementing the complex data type support.
However there seems to be an error when we present the XMLSteramReader
obtained form CXF runtime to JiBX UnmashallingContext which needs work on
process a part of an XML document not as a whole. However when we present an
XMLStreamRead from which it can read the desired element as a whole document
it seems to work.[4]. I suspect this is a bug in JiBX framework and I am
willing to hear expert advice on this.
Any suggestions, advice and tips will be much appreciated !!
Thanks & Regards,
Nilupa
[1] http://github.com/nilupa/cxf
[2] http://github.com/nilupa/cxf/tree/trunk/rt/databinding/jibx/
[3] Error output:
ava.lang.ArrayIndexOutOfBoundsException: Attempt to peek past end of stack
at org.jibx.runtime.IntStack.peek(IntStack.java:231)
at org.jibx.runtime.IntStack.peek(IntStack.java:245)
at
org.jibx.runtime.impl.StAXReaderWrapper.endTag(StAXReaderWrapper.java:159)
at
org.jibx.runtime.impl.StAXReaderWrapper.nextToken(StAXReaderWrapper.java:182)
at
org.jibx.runtime.impl.UnmarshallingContext.accumulateText(UnmarshallingContext.java:840)
at
org.jibx.runtime.impl.UnmarshallingContext.parseContentText(UnmarshallingContext.java:874)
at
org.jibx.runtime.impl.UnmarshallingContext.parseElementText(UnmarshallingContext.java:936)
at org.apache.xcf.jibx.JibxDataReader.read(JibxDataReader.java:57)
at org.apache.xcf.jibx.JibxDataReader.read(JibxDataReader.java:1)
at
org.apache.cxf.interceptor.DocLiteralInInterceptor.getPara(DocLiteralInInterceptor.java:251)
at
org.apache.cxf.interceptor.DocLiteralInInterceptor.handleMessage(DocLiteralInInterceptor.java:127)
at
org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:243)
at
org.apache.cxf.transport.ChainInitiationObserver.onMessage(ChainInitiationObserver.java:110)
at
org.apache.cxf.transport.http_jetty.JettyHTTPDestination.serviceRequest(JettyHTTPDestination.java:313)
at
org.apache.cxf.transport.http_jetty.JettyHTTPDestination.doService(JettyHTTPDestination.java:277)
at
org.apache.cxf.transport.http_jetty.JettyHTTPHandler.handle(JettyHTTPHandler.java:70)
at org.mortbay.jetty.handler.ContextHandler.handle(ContextHandler.java:765)
at
org.mortbay.jetty.handler.ContextHandlerCollection.handle(ContextHandlerCollection.java:230)
at org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:152)
at org.mortbay.jetty.Server.handle(Server.java:326)
at org.mortbay.jetty.HttpConnection.handleRequest(HttpConnection.java:536)
at
org.mortbay.jetty.HttpConnection$RequestHandler.content(HttpConnection.java:930)
at org.mortbay.jetty.HttpParser.parseNext(HttpParser.java:747)
at org.mortbay.jetty.HttpParser.parseAvailable(HttpParser.java:218)
at org.mortbay.jetty.HttpConnection.handle(HttpConnection.java:405)
at
org.mortbay.io.nio.SelectChannelEndPoint.run(SelectChannelEndPoint.java:409)
at
org.mortbay.thread.QueuedThreadPool$PoolThread.run(QueuedThreadPool.java:582)
[4] Work around JibxDataReader.java : line 90
try {
reader =
StaxUtils.createXMLStreamReader(StaxUtils.read(reader));
} catch (Exception e) {
throw new RuntimeException(e);
}
On Fri, Apr 30, 2010 at 11:30 AM, Nilupa Bandara <nilupa.manamperi@gmail.com
> wrote:
> Hi,
>
> At the moment, I am running the sample Web services in debug mode just to
> get a deeper understanding of how the cxf data
> binding architecture works at runtime. I am also planning to look at how
> its done for Axis2 and perhaps we might be able to reuse some of that code
> there. As soon as I have something concrete, will post it to this mailing
> list.
>
> Thanks & Best Regards,
> Nilupa
>
>
> On Fri, Apr 30, 2010 at 2:00 AM, Dennis Sosnoski <dm...@sosnoski.com> wrote:
>
>> I'm curious how the JiBX databinding GSoC project is progressing...
>> anything to discuss yet?
>>
>> JiBX is pretty flexible in how it reads and writes XML, with its own
>> org.jibx.runtime.IXMLReader and IXMLWriter interfaces used to decouple from
>> the details of the parser and writer. Implementations of these interfaces
>> are supplied for working with StAX XMLStreamReader and XMLStreamWriter, and
>> the existing Axis2 support for JiBX should be a good guide for fitting the
>> actual runtime hooks together.
>>
>> Just to make sure I understand how this works, JAX-WS configuration can be
>> used with any type of org.apache.cxf.databinding.DataBinding implementation,
>> right? So someone wanting to use JiBX with a JAX-WS frontend would just need
>> to specify this using their preferred configuration technique (such as
>> cxf-client.xml on the client side).
>>
>> Thanks,
>>
>> - Dennis
>>
>
>
--
Nilupa Bandara
Re: JiBX databinding implementation
Posted by Nilupa Bandara <ni...@gmail.com>.
Hi,
At the moment, I am running the sample Web services in debug mode just to
get a deeper understanding of how the cxf data
binding architecture works at runtime. I am also planning to look at how
its done for Axis2 and perhaps we might be able to reuse some of that code
there. As soon as I have something concrete, will post it to this mailing
list.
Thanks & Best Regards,
Nilupa
On Fri, Apr 30, 2010 at 2:00 AM, Dennis Sosnoski <dm...@sosnoski.com> wrote:
> I'm curious how the JiBX databinding GSoC project is progressing...
> anything to discuss yet?
>
> JiBX is pretty flexible in how it reads and writes XML, with its own
> org.jibx.runtime.IXMLReader and IXMLWriter interfaces used to decouple from
> the details of the parser and writer. Implementations of these interfaces
> are supplied for working with StAX XMLStreamReader and XMLStreamWriter, and
> the existing Axis2 support for JiBX should be a good guide for fitting the
> actual runtime hooks together.
>
> Just to make sure I understand how this works, JAX-WS configuration can be
> used with any type of org.apache.cxf.databinding.DataBinding implementation,
> right? So someone wanting to use JiBX with a JAX-WS frontend would just need
> to specify this using their preferred configuration technique (such as
> cxf-client.xml on the client side).
>
> Thanks,
>
> - Dennis
>