You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@cxf.apache.org by YUL <yu...@dell.com> on 2012/03/27 00:32:11 UTC

How to publish a custom object message through NotificationBroker

Hi All,

I'm a newbie in CXF ws-notification. I found the example in the
distribution/release and it runs fine. However, the example only shows how
to publish a String message to the broker. How do I publish a user-defined
object to the broker and then consumed by the client? 

I tried something as follows:

 notificationBroker.notify("MyTopic", 
               new  Add())
================================================
where Add is an object generated from XSD schema definition using JAXB:

@XmlRootElement(name = "add", namespace = "http://example/")
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "add", namespace = "http://example/", propOrder = {
    "arg0",
    "arg1"
})
public class Add {

    @XmlElement(name = "arg0", namespace = "")
    private int arg0;
    @XmlElement(name = "arg1", namespace = "")
    private int arg1;

    /**
     * 
     * @return
     *     returns int
     */
    public int getArg0() {
        return this.arg0;
    }

    /**
     * 
     * @param arg0
     *     the value for the arg0 property
     */
    public void setArg0(int arg0) {
        this.arg0 = arg0;
    }

    /**
     * 
     * @return
     *     returns int
     */
    public int getArg1() {
        return this.arg1;
    }

    /**
     * 
     * @param arg1
     *     the value for the arg1 property
     */
    public void setArg1(int arg1) {
        this.arg1 = arg1;
    }

}

However, when I ran the code, I got the following exception:

Caused by: javax.xml.bind.MarshalException
 - with linked exception:
[javax.xml.bind.JAXBException: class
com.dell.pg.cim.networking.iominventory.Add nor any of its super class is
known to this context.]

I guess I must have missed something .... would appreciate if someone can
shed light on this issue...

Thanks very much,

YuLing

--
View this message in context: http://cxf.547215.n5.nabble.com/How-to-publish-a-custom-object-message-through-NotificationBroker-tp5596534p5596534.html
Sent from the cxf-dev mailing list archive at Nabble.com.

Re: How to publish a custom object message through NotificationBroker

Posted by Daniel Kulp <dk...@apache.org>.
On Monday, March 26, 2012 03:32:11 PM YUL wrote:
> Hi All,
> 
> I'm a newbie in CXF ws-notification. I found the example in the
> distribution/release and it runs fine. However, the example only shows how
> to publish a String message to the broker. How do I publish a
> user-defined object to the broker and then consumed by the client?

I just committed some changes on trunk for 2.6 to hopefully support this.  I 
had to change a bunch of API's so not really backportable.  

Is there any chance you could try with the 2.6 SNAPSHOT (either build trunk 
yourself or wait till tomorrow for the snaps to deploy) and see how it works 
for you?

One note: I *think* I found a bug in the jaxb-impl that is causing my test 
to fail if assertions are enabled on the JVM and you aren't using CXF.  
Bouncing through the DOM is doing something funny with the namespace 
prefixes or something.  I need to dig into that a bit more.   However, if 
you use CXF as the jax-ws implementation or you don't enable the assertions, 
you should be all set.  

Dan



> 
> I tried something as follows:
> 
>  notificationBroker.notify("MyTopic",
>                new  Add())
> ================================================
> where Add is an object generated from XSD schema definition using JAXB:
> 
> @XmlRootElement(name = "add", namespace = "http://example/")
> @XmlAccessorType(XmlAccessType.FIELD)
> @XmlType(name = "add", namespace = "http://example/", propOrder = {
>     "arg0",
>     "arg1"
> })
> public class Add {
> 
>     @XmlElement(name = "arg0", namespace = "")
>     private int arg0;
>     @XmlElement(name = "arg1", namespace = "")
>     private int arg1;
> 
>     /**
>      *
>      * @return
>      *     returns int
>      */
>     public int getArg0() {
>         return this.arg0;
>     }
> 
>     /**
>      *
>      * @param arg0
>      *     the value for the arg0 property
>      */
>     public void setArg0(int arg0) {
>         this.arg0 = arg0;
>     }
> 
>     /**
>      *
>      * @return
>      *     returns int
>      */
>     public int getArg1() {
>         return this.arg1;
>     }
> 
>     /**
>      *
>      * @param arg1
>      *     the value for the arg1 property
>      */
>     public void setArg1(int arg1) {
>         this.arg1 = arg1;
>     }
> 
> }
> 
> However, when I ran the code, I got the following exception:
> 
> Caused by: javax.xml.bind.MarshalException
>  - with linked exception:
> [javax.xml.bind.JAXBException: class
> com.dell.pg.cim.networking.iominventory.Add nor any of its super class is
> known to this context.]
> 
> I guess I must have missed something .... would appreciate if someone can
> shed light on this issue...
> 
> Thanks very much,
> 
> YuLing
> 
> --
> View this message in context:
> http://cxf.547215.n5.nabble.com/How-to-publish-a-custom-object-message-th
> rough-NotificationBroker-tp5596534p5596534.html Sent from the cxf-dev
> 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 publish a custom object message through NotificationBroker

Posted by Daniel Kulp <dk...@apache.org>.
On Monday, March 26, 2012 03:32:11 PM YUL wrote:
> Hi All,
> 
> I'm a newbie in CXF ws-notification. I found the example in the
> distribution/release and it runs fine. However, the example only shows how
> to publish a String message to the broker. How do I publish a
> user-defined object to the broker and then consumed by the client?

Currently, it's not ideal.  You would need to do something like:
            Object msg = new Add(); ///your object here
            JAXBContext c = JAXBContext.newInstance(msg.getClass());
            DOMResult result = new DOMResult();
            c.createMarshaller().marshal(msg, result);
            msg = result.getNode();
            if (msg instanceof Document) {
                msg = ((Document)msg).getDocumentElement();
            }

to convert your object to a DOM and pass that to the notify method.   On the 
receiving side, you always get a DOM object right now anyway do you would 
need to do the reverse.   

If I get some time in the next few days, I may update the code a bit to 
support this better.   There are a couple of options:

1) CXF and JAX-WS RI - I could add a "JAXBContext" parameter to the 
NotificationBroker and pretty much do the above automatically for you.  You 
would need to create a JAXBContext with whatever classes you may send and 
we'll convert to DOM and pass it.

2) CXF only - I can add a "Class<?> ... classes" parameter and pass that 
into CXF to add to the context that CXF creates.   This would perform much 
better than (1) as we wouldn't need to bounce through the DOM.   There isn't 
an easy way to do that for the RI though.    I MIGHT be able to get this to 
then drop down to (1) if not using CXF.   Not sure.

I can likely do the same for the Consumer class as well.

I personally prefer the (2) option as it performs better, but that may 
increase it's dependency on CXF.  I don't see that as an issue, but some 
may.


Dan




> 
> I tried something as follows:
> 
>  notificationBroker.notify("MyTopic",
>                new  Add())
> ================================================
> where Add is an object generated from XSD schema definition using JAXB:
> 
> @XmlRootElement(name = "add", namespace = "http://example/")
> @XmlAccessorType(XmlAccessType.FIELD)
> @XmlType(name = "add", namespace = "http://example/", propOrder = {
>     "arg0",
>     "arg1"
> })
> public class Add {
> 
>     @XmlElement(name = "arg0", namespace = "")
>     private int arg0;
>     @XmlElement(name = "arg1", namespace = "")
>     private int arg1;
> 
>     /**
>      *
>      * @return
>      *     returns int
>      */
>     public int getArg0() {
>         return this.arg0;
>     }
> 
>     /**
>      *
>      * @param arg0
>      *     the value for the arg0 property
>      */
>     public void setArg0(int arg0) {
>         this.arg0 = arg0;
>     }
> 
>     /**
>      *
>      * @return
>      *     returns int
>      */
>     public int getArg1() {
>         return this.arg1;
>     }
> 
>     /**
>      *
>      * @param arg1
>      *     the value for the arg1 property
>      */
>     public void setArg1(int arg1) {
>         this.arg1 = arg1;
>     }
> 
> }
> 
> However, when I ran the code, I got the following exception:
> 
> Caused by: javax.xml.bind.MarshalException
>  - with linked exception:
> [javax.xml.bind.JAXBException: class
> com.dell.pg.cim.networking.iominventory.Add nor any of its super class is
> known to this context.]
> 
> I guess I must have missed something .... would appreciate if someone can
> shed light on this issue...
> 
> Thanks very much,
> 
> YuLing
> 
> --
> View this message in context:
> http://cxf.547215.n5.nabble.com/How-to-publish-a-custom-object-message-th
> rough-NotificationBroker-tp5596534p5596534.html Sent from the cxf-dev
> mailing list archive at Nabble.com.
-- 
Daniel Kulp
dkulp@apache.org - http://dankulp.com/blog
Talend Community Coder - http://coders.talend.com