You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@cxf.apache.org by Will Johnson <wi...@gmail.com> on 2009/12/11 20:56:05 UTC

implementor - multiple @WebService implemented interfaces

I've been using cxf for a while now and everything is going well until I
tried to have a class implement two different web service interfaces.  For
example:

 

@WebService

public interface Foo {  .  }

 

@WebService

public interface Bar {  .  }

 

public class MyService implements Foo, Bar { .. }

 

I then tried to do something like the following:

 

EndpointImpl endpointImpl = (EndpointImpl) Endpoint.publish("foo",
myService);

endpointImpl.setImplementorClass(Foo.class);

endpointImpl.setBus(bus);

 

// now publish the same implementor but with a different ws interface

endpointImpl = (EndpointImpl) Endpoint.publish("bar", myService);

endpointImpl.setImplementorClass(Bar.class);

endpointImpl.setBus(bus);

 

However I always end up with the same service descriptor registered under
two names (the WSDL for Foo registered for both "/foo" and "/bar").  Is
there a way to tell cxf/jaxws to generate the wsdl from a specific interface
definitions instead of the implementor class?

 

-          will

 


RE: implementor - multiple @WebService implemented interfaces

Posted by Will Johnson <wi...@gmail.com>.
I made the test and found a useful piece of information:

// this works
EndpointImpl epi = (EndpointImpl) Endpoint.create(impl);
epi.setImplementorClass(c);
epi.publish(name);

// this does not, which is what I did originally
EndpointImpl epi = (EndpointImpl) Endpoint.create(name, impl);
epi.setImplementorClass(c);
epi.publish();

thanks for the help

- will



-----Original Message-----
From: Daniel Kulp [mailto:dkulp@apache.org] 
Sent: Monday, December 14, 2009 10:57 AM
To: users@cxf.apache.org
Cc: Will Johnson
Subject: Re: implementor - multiple @WebService implemented interfaces

On Fri December 11 2009 5:14:14 pm Will Johnson wrote:
> I tried the create instead of publish route, that didn't seem to have any
> effect.

Hmm. .  That's not good.   Can you create a small sample that demonstrates 
that and log a bug?    That SHOULD have worked, I think.


> As for the ServerFactoryBean, I'm not quite sure how that works.  It seems
> to only take a single address and I have multiple services hanging off the
> same servlet.

You would create a new JaxWsServerFactoryBean for each address you want 
something deployed on.     You can create a bunch of them each with
different 
(or same) impls and with different addresses.

Basically, in theory, Endpoint.create just creates a JaxWsServerFactoryBean 
(and a few other supporting objects) and wrappers it with the EndpointImpl.

The publish then calls off to the JaxWsServerFactoryBean to do the real
work.   
That is why the Endpoint.create thing SHOULD have worked.

Dan




> 
> - will
> 
> -----Original Message-----
> From: Daniel Kulp [mailto:dkulp@apache.org]
> Sent: Friday, December 11, 2009 4:13 PM
> To: users@cxf.apache.org
> Cc: Will Johnson
> Subject: Re: implementor - multiple @WebService implemented interfaces
> 
> 
> Two thoughts:
> 
> 1) This MIGHT work if you use "Endpoint.create(...)" instead of
> "Endpoint.publish(...)"  and then call publish on the endpoint after
>  setting
> 
> the properties.    By the time "Endpoint.publish(..)" returns, everything
>  is
> 
> completely setup.
> 
> 2) You SHOULD be able to do this if you use the JaxWsServerFactoryBean
> instead
> of using the Endpoint/EndpointImpl things.
> 
> See the docs on the simple front end:
> http://cxf.apache.org/docs/simple-frontend.html
> which uses the ServerFactoryBean (the superclass of
JaxWsServerFactoryBean)
> for some ideas.
> 
> Dan
> 
> On Fri December 11 2009 2:56:05 pm Will Johnson wrote:
> > I've been using cxf for a while now and everything is going well until I
> > tried to have a class implement two different web service interfaces. 
> > For example:
> >
> >
> >
> > @WebService
> >
> > public interface Foo {  .  }
> >
> >
> >
> > @WebService
> >
> > public interface Bar {  .  }
> >
> >
> >
> > public class MyService implements Foo, Bar { .. }
> >
> >
> >
> > I then tried to do something like the following:
> >
> >
> >
> > EndpointImpl endpointImpl = (EndpointImpl) Endpoint.publish("foo",
> > myService);
> >
> > endpointImpl.setImplementorClass(Foo.class);
> >
> > endpointImpl.setBus(bus);
> >
> >
> >
> > // now publish the same implementor but with a different ws interface
> >
> > endpointImpl = (EndpointImpl) Endpoint.publish("bar", myService);
> >
> > endpointImpl.setImplementorClass(Bar.class);
> >
> > endpointImpl.setBus(bus);
> >
> >
> >
> > However I always end up with the same service descriptor registered
under
> > two names (the WSDL for Foo registered for both "/foo" and "/bar").  Is
> > there a way to tell cxf/jaxws to generate the wsdl from a specific
> >  interface definitions instead of the implementor class?
> >
> >
> >
> > -          will
> 

-- 
Daniel Kulp
dkulp@apache.org
http://www.dankulp.com/blog


RE: implementor - multiple @WebService implemented interfaces

Posted by Will Johnson <wi...@gmail.com>.
And just in case anyone wants to see the sample:

import javax.jws.WebMethod;
import javax.jws.WebService;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.xml.ws.Endpoint;

import org.apache.cxf.jaxws.EndpointImpl;
import org.apache.cxf.transport.servlet.CXFNonSpringServlet;
import org.junit.Test;
import org.mortbay.jetty.Server;
import org.mortbay.jetty.servlet.Context;
import org.mortbay.jetty.servlet.ServletHolder;


public class CxfMultiInterfaceSample {

  @Test
  public void testMultipleSchemas() throws Exception {

    // setup a simple jetty server
    Server server = new Server(8080);
    Context root = new Context(server, "/", Context.SESSIONS);
    root.addServlet(new ServletHolder(new WebServiceServlet()), "/*");
    server.start();

    // hang out forever so we can see what's going on in a browser
    while (true) {
      Thread.sleep(100000);
    }
  }

  // registers all the endpoints
  public class WebServiceServlet extends CXFNonSpringServlet {

    // my common implementor
    FooBarImpl impl = new FooBarImpl();

    /** {@inheritDoc} */
    @Override
    public void loadBus(ServletConfig servletConfig) throws ServletException
{
      super.loadBus(servletConfig);
      publishService("/foo", Foo.class);
      publishService("/bar", Bar.class);
    }

    private void publishService(String name, Class<?> c) {
      // this does not work
      //EndpointImpl epi = (EndpointImpl) Endpoint.publish(name, new
FooBarImpl() );
      //epi.setBus(getBus());

      // what was suggested by Daniel Kulp
      EndpointImpl epi = (EndpointImpl) Endpoint.create(impl);
      epi.setImplementorClass(c);
      epi.publish(name);
    }
  }

  @WebService
  public interface Foo {
    @WebMethod public int getFoo();
  }

  @WebService
  public interface Bar {
    @WebMethod public int getBar();
  }

  @WebService
  public class FooBarImpl implements Foo, Bar {
    @WebMethod public int getFoo() { return 7; }
    @WebMethod public int getBar() { return 8; }
  }

}

-----Original Message-----
From: Daniel Kulp [mailto:dkulp@apache.org] 
Sent: Monday, December 14, 2009 10:57 AM
To: users@cxf.apache.org
Cc: Will Johnson
Subject: Re: implementor - multiple @WebService implemented interfaces

On Fri December 11 2009 5:14:14 pm Will Johnson wrote:
> I tried the create instead of publish route, that didn't seem to have any
> effect.

Hmm. .  That's not good.   Can you create a small sample that demonstrates 
that and log a bug?    That SHOULD have worked, I think.


> As for the ServerFactoryBean, I'm not quite sure how that works.  It seems
> to only take a single address and I have multiple services hanging off the
> same servlet.

You would create a new JaxWsServerFactoryBean for each address you want 
something deployed on.     You can create a bunch of them each with
different 
(or same) impls and with different addresses.

Basically, in theory, Endpoint.create just creates a JaxWsServerFactoryBean 
(and a few other supporting objects) and wrappers it with the EndpointImpl.

The publish then calls off to the JaxWsServerFactoryBean to do the real
work.   
That is why the Endpoint.create thing SHOULD have worked.

Dan




> 
> - will
> 
> -----Original Message-----
> From: Daniel Kulp [mailto:dkulp@apache.org]
> Sent: Friday, December 11, 2009 4:13 PM
> To: users@cxf.apache.org
> Cc: Will Johnson
> Subject: Re: implementor - multiple @WebService implemented interfaces
> 
> 
> Two thoughts:
> 
> 1) This MIGHT work if you use "Endpoint.create(...)" instead of
> "Endpoint.publish(...)"  and then call publish on the endpoint after
>  setting
> 
> the properties.    By the time "Endpoint.publish(..)" returns, everything
>  is
> 
> completely setup.
> 
> 2) You SHOULD be able to do this if you use the JaxWsServerFactoryBean
> instead
> of using the Endpoint/EndpointImpl things.
> 
> See the docs on the simple front end:
> http://cxf.apache.org/docs/simple-frontend.html
> which uses the ServerFactoryBean (the superclass of
JaxWsServerFactoryBean)
> for some ideas.
> 
> Dan
> 
> On Fri December 11 2009 2:56:05 pm Will Johnson wrote:
> > I've been using cxf for a while now and everything is going well until I
> > tried to have a class implement two different web service interfaces. 
> > For example:
> >
> >
> >
> > @WebService
> >
> > public interface Foo {  .  }
> >
> >
> >
> > @WebService
> >
> > public interface Bar {  .  }
> >
> >
> >
> > public class MyService implements Foo, Bar { .. }
> >
> >
> >
> > I then tried to do something like the following:
> >
> >
> >
> > EndpointImpl endpointImpl = (EndpointImpl) Endpoint.publish("foo",
> > myService);
> >
> > endpointImpl.setImplementorClass(Foo.class);
> >
> > endpointImpl.setBus(bus);
> >
> >
> >
> > // now publish the same implementor but with a different ws interface
> >
> > endpointImpl = (EndpointImpl) Endpoint.publish("bar", myService);
> >
> > endpointImpl.setImplementorClass(Bar.class);
> >
> > endpointImpl.setBus(bus);
> >
> >
> >
> > However I always end up with the same service descriptor registered
under
> > two names (the WSDL for Foo registered for both "/foo" and "/bar").  Is
> > there a way to tell cxf/jaxws to generate the wsdl from a specific
> >  interface definitions instead of the implementor class?
> >
> >
> >
> > -          will
> 

-- 
Daniel Kulp
dkulp@apache.org
http://www.dankulp.com/blog


Re: implementor - multiple @WebService implemented interfaces

Posted by Daniel Kulp <dk...@apache.org>.
On Fri December 11 2009 5:14:14 pm Will Johnson wrote:
> I tried the create instead of publish route, that didn't seem to have any
> effect.

Hmm. .  That's not good.   Can you create a small sample that demonstrates 
that and log a bug?    That SHOULD have worked, I think.


> As for the ServerFactoryBean, I'm not quite sure how that works.  It seems
> to only take a single address and I have multiple services hanging off the
> same servlet.

You would create a new JaxWsServerFactoryBean for each address you want 
something deployed on.     You can create a bunch of them each with different 
(or same) impls and with different addresses.

Basically, in theory, Endpoint.create just creates a JaxWsServerFactoryBean 
(and a few other supporting objects) and wrappers it with the EndpointImpl.    
The publish then calls off to the JaxWsServerFactoryBean to do the real work.   
That is why the Endpoint.create thing SHOULD have worked.

Dan




> 
> - will
> 
> -----Original Message-----
> From: Daniel Kulp [mailto:dkulp@apache.org]
> Sent: Friday, December 11, 2009 4:13 PM
> To: users@cxf.apache.org
> Cc: Will Johnson
> Subject: Re: implementor - multiple @WebService implemented interfaces
> 
> 
> Two thoughts:
> 
> 1) This MIGHT work if you use "Endpoint.create(...)" instead of
> "Endpoint.publish(...)"  and then call publish on the endpoint after
>  setting
> 
> the properties.    By the time "Endpoint.publish(..)" returns, everything
>  is
> 
> completely setup.
> 
> 2) You SHOULD be able to do this if you use the JaxWsServerFactoryBean
> instead
> of using the Endpoint/EndpointImpl things.
> 
> See the docs on the simple front end:
> http://cxf.apache.org/docs/simple-frontend.html
> which uses the ServerFactoryBean (the superclass of JaxWsServerFactoryBean)
> for some ideas.
> 
> Dan
> 
> On Fri December 11 2009 2:56:05 pm Will Johnson wrote:
> > I've been using cxf for a while now and everything is going well until I
> > tried to have a class implement two different web service interfaces. 
> > For example:
> >
> >
> >
> > @WebService
> >
> > public interface Foo {  .  }
> >
> >
> >
> > @WebService
> >
> > public interface Bar {  .  }
> >
> >
> >
> > public class MyService implements Foo, Bar { .. }
> >
> >
> >
> > I then tried to do something like the following:
> >
> >
> >
> > EndpointImpl endpointImpl = (EndpointImpl) Endpoint.publish("foo",
> > myService);
> >
> > endpointImpl.setImplementorClass(Foo.class);
> >
> > endpointImpl.setBus(bus);
> >
> >
> >
> > // now publish the same implementor but with a different ws interface
> >
> > endpointImpl = (EndpointImpl) Endpoint.publish("bar", myService);
> >
> > endpointImpl.setImplementorClass(Bar.class);
> >
> > endpointImpl.setBus(bus);
> >
> >
> >
> > However I always end up with the same service descriptor registered under
> > two names (the WSDL for Foo registered for both "/foo" and "/bar").  Is
> > there a way to tell cxf/jaxws to generate the wsdl from a specific
> >  interface definitions instead of the implementor class?
> >
> >
> >
> > -          will
> 

-- 
Daniel Kulp
dkulp@apache.org
http://www.dankulp.com/blog

RE: implementor - multiple @WebService implemented interfaces

Posted by Will Johnson <wi...@gmail.com>.
I tried the create instead of publish route, that didn't seem to have any
effect.

As for the ServerFactoryBean, I'm not quite sure how that works.  It seems
to only take a single address and I have multiple services hanging off the
same servlet.

- will

-----Original Message-----
From: Daniel Kulp [mailto:dkulp@apache.org] 
Sent: Friday, December 11, 2009 4:13 PM
To: users@cxf.apache.org
Cc: Will Johnson
Subject: Re: implementor - multiple @WebService implemented interfaces


Two thoughts:

1) This MIGHT work if you use "Endpoint.create(...)" instead of 
"Endpoint.publish(...)"  and then call publish on the endpoint after setting

the properties.    By the time "Endpoint.publish(..)" returns, everything is

completely setup.

2) You SHOULD be able to do this if you use the JaxWsServerFactoryBean
instead 
of using the Endpoint/EndpointImpl things.   

See the docs on the simple front end:
http://cxf.apache.org/docs/simple-frontend.html
which uses the ServerFactoryBean (the superclass of JaxWsServerFactoryBean) 
for some ideas.

Dan



On Fri December 11 2009 2:56:05 pm Will Johnson wrote:
> I've been using cxf for a while now and everything is going well until I
> tried to have a class implement two different web service interfaces.  For
> example:
> 
> 
> 
> @WebService
> 
> public interface Foo {  .  }
> 
> 
> 
> @WebService
> 
> public interface Bar {  .  }
> 
> 
> 
> public class MyService implements Foo, Bar { .. }
> 
> 
> 
> I then tried to do something like the following:
> 
> 
> 
> EndpointImpl endpointImpl = (EndpointImpl) Endpoint.publish("foo",
> myService);
> 
> endpointImpl.setImplementorClass(Foo.class);
> 
> endpointImpl.setBus(bus);
> 
> 
> 
> // now publish the same implementor but with a different ws interface
> 
> endpointImpl = (EndpointImpl) Endpoint.publish("bar", myService);
> 
> endpointImpl.setImplementorClass(Bar.class);
> 
> endpointImpl.setBus(bus);
> 
> 
> 
> However I always end up with the same service descriptor registered under
> two names (the WSDL for Foo registered for both "/foo" and "/bar").  Is
> there a way to tell cxf/jaxws to generate the wsdl from a specific
>  interface definitions instead of the implementor class?
> 
> 
> 
> -          will
> 

-- 
Daniel Kulp
dkulp@apache.org
http://www.dankulp.com/blog


Re: implementor - multiple @WebService implemented interfaces

Posted by Daniel Kulp <dk...@apache.org>.
Two thoughts:

1) This MIGHT work if you use "Endpoint.create(...)" instead of 
"Endpoint.publish(...)"  and then call publish on the endpoint after setting 
the properties.    By the time "Endpoint.publish(..)" returns, everything is 
completely setup.

2) You SHOULD be able to do this if you use the JaxWsServerFactoryBean instead 
of using the Endpoint/EndpointImpl things.   

See the docs on the simple front end:
http://cxf.apache.org/docs/simple-frontend.html
which uses the ServerFactoryBean (the superclass of JaxWsServerFactoryBean) 
for some ideas.

Dan



On Fri December 11 2009 2:56:05 pm Will Johnson wrote:
> I've been using cxf for a while now and everything is going well until I
> tried to have a class implement two different web service interfaces.  For
> example:
> 
> 
> 
> @WebService
> 
> public interface Foo {  .  }
> 
> 
> 
> @WebService
> 
> public interface Bar {  .  }
> 
> 
> 
> public class MyService implements Foo, Bar { .. }
> 
> 
> 
> I then tried to do something like the following:
> 
> 
> 
> EndpointImpl endpointImpl = (EndpointImpl) Endpoint.publish("foo",
> myService);
> 
> endpointImpl.setImplementorClass(Foo.class);
> 
> endpointImpl.setBus(bus);
> 
> 
> 
> // now publish the same implementor but with a different ws interface
> 
> endpointImpl = (EndpointImpl) Endpoint.publish("bar", myService);
> 
> endpointImpl.setImplementorClass(Bar.class);
> 
> endpointImpl.setBus(bus);
> 
> 
> 
> However I always end up with the same service descriptor registered under
> two names (the WSDL for Foo registered for both "/foo" and "/bar").  Is
> there a way to tell cxf/jaxws to generate the wsdl from a specific
>  interface definitions instead of the implementor class?
> 
> 
> 
> -          will
> 

-- 
Daniel Kulp
dkulp@apache.org
http://www.dankulp.com/blog