You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@cxf.apache.org by "Bokde, Dhiraj" <DB...@iona.com> on 2007/08/17 21:21:31 UTC

Generic Provider server and WSDL metadata

Hi,

I am trying to build a generic server using Provider<DOMSource>. But I
want to make the WSDL metadata, wsdlLocation, serviceName, portName,
etc. to be user configurable, without having to re-compile the Provider
with new WebServiceProvider annotations for every new WSDL. 

I thought I'd be able to do this with an empty WebServiceProvider
annotation for my Provider like below:

<snip>
@WebServiceProvider()
@ServiceMode(value = Service.Mode.MESSAGE)
public final class GenericMessageProvider implements Provider<DOMSource>
{
<snip>

And the jaxws:endpoint element in a spring container cxf-beans.xml, like
below:

<snip>
	<jaxws:endpoint id="myEndpoint" implementor="#genericProvider"
		address="/myLocation/" serviceName="msp:MyService"
		wsdlLocation="classpath:wsdl/MyWSDL.wsdl"
		xmlns:msp="http://my.service">
	</jaxws:endpoint>
<snip>

But this throws an NPE when I load the cxf-beans.xml using Tomcat. The
relevant log4j logs are attached. 

Any ideas what's causing this?

Thanks,
Dhiraj.

RE: Generic Provider server and WSDL metadata

Posted by "Liu, Jervis" <jl...@iona.com>.
Hi Dhiraj, I just filed CXF-935 for this. So the problem is that when Provider's WSDL is supplied from spring configuration (so it is still WSDL-first, build service model from WSDL), the endpoint point should be from WSDL instead of from Provider class name.

Cheers,
Jervis

> -----Original Message-----
> From: Bokde, Dhiraj [mailto:DBOKDE@iona.com]
> Sent: 2007?8?23? 2:55
> To: cxf-user@incubator.apache.org
> Subject: RE: Generic Provider<DOMSource> server and WSDL metadata
> 
> 
> > >
> > the JAX-WS 'endpoint' element in Spring XML configuration 
> does indeed
> > provide/override the info in the annotation. The reason why it does
> not
> > work? It might be a bug. If you have access to CXF source code, in
> > ReflectionServiceFactoryBean.java line 956, method 
> getEndpointInfo():
> > 
> > public EndpointInfo getEndpointInfo() {
> >         return getService().getEndpointInfo(getEndpointName());
> > }
> > 
> > the getService() returns the service model built from WSDL file, but
> > somehow it does not contain an endpoint whose name is
> getEndpointName()
> > which might come from java class. Could you please report a Jira for
> this.
> > 
> > BTW, you may want to try to add an endpointname attribute into your
> spring
> > config, just a wild guess, not sure if it works. ;-)
> > 
> > <snip>
> > 	<jaxws:endpoint id="myEndpoint" implementor="#genericProvider"
> > endpointName="endpointName is the port qname in wsdl"
> > 		address="/myLocation/" serviceName="msp:MyService"
> > 		wsdlLocation="classpath:wsdl/MyWSDL.wsdl"
> > 		xmlns:msp="http://my.service">
> > 	</jaxws:endpoint>
> > <snip>
> > 
> [Bokde, Dhiraj] I debugged it a little, and the 
> getEndpointName() method
> returns GenericProviderService instead of the serviceName in the
> endpoint. 
> I have tried adding the endpointName attribute as well and it didn't
> make any difference. 
> 

----------------------------
IONA Technologies PLC (registered in Ireland)
Registered Number: 171387
Registered Address: The IONA Building, Shelbourne Road, Dublin 4, Ireland

RE: Generic Provider server and WSDL metadata

Posted by "Bokde, Dhiraj" <DB...@iona.com>.
> >
> the JAX-WS 'endpoint' element in Spring XML configuration does indeed
> provide/override the info in the annotation. The reason why it does
not
> work? It might be a bug. If you have access to CXF source code, in
> ReflectionServiceFactoryBean.java line 956, method getEndpointInfo():
> 
> public EndpointInfo getEndpointInfo() {
>         return getService().getEndpointInfo(getEndpointName());
> }
> 
> the getService() returns the service model built from WSDL file, but
> somehow it does not contain an endpoint whose name is
getEndpointName()
> which might come from java class. Could you please report a Jira for
this.
> 
> BTW, you may want to try to add an endpointname attribute into your
spring
> config, just a wild guess, not sure if it works. ;-)
> 
> <snip>
> 	<jaxws:endpoint id="myEndpoint" implementor="#genericProvider"
> endpointName="endpointName is the port qname in wsdl"
> 		address="/myLocation/" serviceName="msp:MyService"
> 		wsdlLocation="classpath:wsdl/MyWSDL.wsdl"
> 		xmlns:msp="http://my.service">
> 	</jaxws:endpoint>
> <snip>
> 
[Bokde, Dhiraj] I debugged it a little, and the getEndpointName() method
returns GenericProviderService instead of the serviceName in the
endpoint. 
I have tried adding the endpointName attribute as well and it didn't
make any difference. 

RE: Generic Provider server and WSDL metadata

Posted by "Liu, Jervis" <jl...@iona.com>.
Comment in-line.

> -----Original Message-----
> From: Bokde, Dhiraj [mailto:DBOKDE@iona.com]
> Sent: 2007?8?22? 10:17
> To: cxf-user@incubator.apache.org
> Subject: RE: Generic Provider<DOMSource> server and WSDL metadata
> 
> 
> Hi Liu,
> 
> Find my response inline:
> 
> > -----Original Message-----
> > From: Liu, Jervis [mailto:jliu@iona.com]
> > Sent: Sunday, August 19, 2007 8:35 PM
> > To: cxf-user@incubator.apache.org
> > Subject: RE: Generic Provider<DOMSource> server and WSDL metadata
> > 
> > Hi Dhiraj, it looks like sth wrong in your WSDL, most likely the
> service
> > name defined in your WSDL does not match with the service name
> specificed
> > in your spring cfg file.
> > 
> 
> [Bokde, Dhiraj] I added the metadata parameters to the
> @WebServiceProvider annotation and the application worked as 
> I expected.
> In other words, when the WSDL information is compiled in the 
> annotation,
> the published WSDL is the original WSDL being referenced and 
> the JAX-WS
> properties WSDL_SERVICE, etc. point to the application's WSDL. 
> When the annotation does not have the WSDL information, I see the
> exception I had attached before. If the JAX-WS 'endpoint' element does
> not have the service name and port name and the annotation is empty
> (@WebServiceProvider()), CXF looks for a Service named
> 'GenericMessageProviderService' with a WSDL operation 'invoke' in the
> WSDL provided in wsdlLocation in the 'endpoint' element. 
> 
> In other words, if the annotation does not have any WSDL 
> meta-data, CXF
> assumes that the application is SEI and not Provider based 
> (despite the
> fact that 'GenericMessageProvider' implements Provider).
> 

Internally in CXF, the service model is populated from WSDL file if wsdlLocation is specified in annotation or in spring config file otherwise the service model is populated from Java class (code-first approache). The service  model does not distingush SEI or Provider. In your case, if you use an empty @WebServiceProvider() annotation, the corresponding service model is created from GenericMessageProvider, thus the service name is 'GenericMessageProviderService' (mapped from java class name by default) and only operation available in this model is invoke, as invoke is the only public java method in GenericMessageProvider class. The WSDL metadata stuff wsdlLocation, serviceName, portName etc is retrieved from the service model.


> > BTW, I don't really get the reason why you want to access 
> to the WSDL
> > metadata like wsdlLocation, serviceName, portName, 
> operation name etc.
> > JAX-WS SEI is WSDL-centric, there is always a direct mapping between
> SEI's
> > java types/method and WSDL's types/operations, i.e., you look at the
> WSDL,
> > then you know what kind of request is a valid request that 
> can be sent
> to
> > server. JAX-WS Provider/Dispatch interface however, is not
> WSDL-centric,
> > you do not need a wsdl at all to work with a Provider 
> server. The only
> > thing a client who wants to invoke a Provider service need 
> to know is
> the
> > service publishing address. Of course, you can still specify a WSDL
> > through @WebServiceProvider() or spring configuration, but your
> Provider
> > service is not bound by this WSDL. In another word, WSDL 
> metadata info
> > like wsdlLocation, serviceName, portName, operation name 
> for Provider
> are
> > no use and should not be used.
> > 
> 
> [Bokde, Dhiraj] This is needed in generic XML oriented 
> frameworks where
> the user needs the ability to use the Provider interface to 
> avoid having
> to generate Java code from WSDL, but still needs the ability to work
> with a WSDL. For example, it may need to verify compliance of messages
> with the underlying WSDL, basically use Service meta-data 
> that can only
> come from a WSDL. 
> 
> I don't believe the use case is the real issue here. My questions are:
> 
> Is the annotation supposed to be the only source of WSDL 
> metadata for a
> JAX-WS Provider based server? Or, is the JAX-WS endpoint element in
> Spring XML configuration supposed to substitute/override the 
> metadata in
> the annotation? If so, why isn't it working? 
> 
> If the JAX-WS 'endpoint' element in Spring XML configuration cannot
> provide/override the info in the annotation, 
> @WebServiceProvider must be
> one of those poor 'compile time only' configuration mechanisms of the
> JAX-WS framework. 
> 
the JAX-WS 'endpoint' element in Spring XML configuration does indeed provide/override the info in the annotation. The reason why it does not work? It might be a bug. If you have access to CXF source code, in ReflectionServiceFactoryBean.java line 956, method getEndpointInfo():

public EndpointInfo getEndpointInfo() {
        return getService().getEndpointInfo(getEndpointName());
}

the getService() returns the service model built from WSDL file, but somehow it does not contain an endpoint whose name is getEndpointName() which might come from java class. Could you please report a Jira for this.

BTW, you may want to try to add an endpointname attribute into your spring config, just a wild guess, not sure if it works. ;-)

<snip>
	<jaxws:endpoint id="myEndpoint" implementor="#genericProvider" endpointName="endpointName is the port qname in wsdl"
		address="/myLocation/" serviceName="msp:MyService"
		wsdlLocation="classpath:wsdl/MyWSDL.wsdl"
		xmlns:msp="http://my.service">
	</jaxws:endpoint>
<snip>

> Thanks,
> Dhiraj. 
> 

----------------------------
IONA Technologies PLC (registered in Ireland)
Registered Number: 171387
Registered Address: The IONA Building, Shelbourne Road, Dublin 4, Ireland

RE: Generic Provider server and WSDL metadata

Posted by "Bokde, Dhiraj" <DB...@iona.com>.
Hi Liu,

Find my response inline:

> -----Original Message-----
> From: Liu, Jervis [mailto:jliu@iona.com]
> Sent: Sunday, August 19, 2007 8:35 PM
> To: cxf-user@incubator.apache.org
> Subject: RE: Generic Provider<DOMSource> server and WSDL metadata
> 
> Hi Dhiraj, it looks like sth wrong in your WSDL, most likely the
service
> name defined in your WSDL does not match with the service name
specificed
> in your spring cfg file.
> 

[Bokde, Dhiraj] I added the metadata parameters to the
@WebServiceProvider annotation and the application worked as I expected.
In other words, when the WSDL information is compiled in the annotation,
the published WSDL is the original WSDL being referenced and the JAX-WS
properties WSDL_SERVICE, etc. point to the application's WSDL. 
When the annotation does not have the WSDL information, I see the
exception I had attached before. If the JAX-WS 'endpoint' element does
not have the service name and port name and the annotation is empty
(@WebServiceProvider()), CXF looks for a Service named
'GenericMessageProviderService' with a WSDL operation 'invoke' in the
WSDL provided in wsdlLocation in the 'endpoint' element. 

In other words, if the annotation does not have any WSDL meta-data, CXF
assumes that the application is SEI and not Provider based (despite the
fact that 'GenericMessageProvider' implements Provider).

> BTW, I don't really get the reason why you want to access to the WSDL
> metadata like wsdlLocation, serviceName, portName, operation name etc.
> JAX-WS SEI is WSDL-centric, there is always a direct mapping between
SEI's
> java types/method and WSDL's types/operations, i.e., you look at the
WSDL,
> then you know what kind of request is a valid request that can be sent
to
> server. JAX-WS Provider/Dispatch interface however, is not
WSDL-centric,
> you do not need a wsdl at all to work with a Provider server. The only
> thing a client who wants to invoke a Provider service need to know is
the
> service publishing address. Of course, you can still specify a WSDL
> through @WebServiceProvider() or spring configuration, but your
Provider
> service is not bound by this WSDL. In another word, WSDL metadata info
> like wsdlLocation, serviceName, portName, operation name for Provider
are
> no use and should not be used.
> 

[Bokde, Dhiraj] This is needed in generic XML oriented frameworks where
the user needs the ability to use the Provider interface to avoid having
to generate Java code from WSDL, but still needs the ability to work
with a WSDL. For example, it may need to verify compliance of messages
with the underlying WSDL, basically use Service meta-data that can only
come from a WSDL. 

I don't believe the use case is the real issue here. My questions are:

Is the annotation supposed to be the only source of WSDL metadata for a
JAX-WS Provider based server? Or, is the JAX-WS endpoint element in
Spring XML configuration supposed to substitute/override the metadata in
the annotation? If so, why isn't it working? 

If the JAX-WS 'endpoint' element in Spring XML configuration cannot
provide/override the info in the annotation, @WebServiceProvider must be
one of those poor 'compile time only' configuration mechanisms of the
JAX-WS framework. 

Thanks,
Dhiraj. 

RE: Generic Provider server and WSDL metadata

Posted by "Liu, Jervis" <jl...@iona.com>.
Hi Dhiraj, it looks like sth wrong in your WSDL, most likely the service name defined in your WSDL does not match with the service name specificed in your spring cfg file. 

BTW, I don't really get the reason why you want to access to the WSDL metadata like wsdlLocation, serviceName, portName, operation name etc. JAX-WS SEI is WSDL-centric, there is always a direct mapping between SEI's java types/method and WSDL's types/operations, i.e., you look at the WSDL, then you know what kind of request is a valid request that can be sent to server. JAX-WS Provider/Dispatch interface however, is not WSDL-centric, you do not need a wsdl at all to work with a Provider server. The only thing a client who wants to invoke a Provider service need to know is the service publishing address. Of course, you can still specify a WSDL through @WebServiceProvider() or spring configuration, but your Provider service is not bound by this WSDL. In another word, WSDL metadata info like wsdlLocation, serviceName, portName, operation name for Provider are no use and should not be used.

Cheers,
Jervis

> -----Original Message-----
> From: Dan Diephouse [mailto:dan@envoisolutions.com]
> Sent: 2007?8?19? 12:31
> To: cxf-user@incubator.apache.org
> Subject: Re: Generic Provider<DOMSource> server and WSDL metadata
> 
> 
> Hmmm I have no idea how that's occurring... Any chance your 
> wsdl has zero
> operations in it?
> 
> - Dan
> 
> On 8/17/07, Bokde, Dhiraj <DB...@iona.com> wrote:
> >
> > Hi,
> >
> > I am trying to build a generic server using 
> Provider<DOMSource>. But I
> > want to make the WSDL metadata, wsdlLocation, serviceName, portName,
> > etc. to be user configurable, without having to re-compile 
> the Provider
> > with new WebServiceProvider annotations for every new WSDL.
> >
> > I thought I'd be able to do this with an empty WebServiceProvider
> > annotation for my Provider like below:
> >
> > <snip>
> > @WebServiceProvider()
> > @ServiceMode(value = Service.Mode.MESSAGE)
> > public final class GenericMessageProvider implements 
> Provider<DOMSource>
> > {
> > <snip>
> >
> > And the jaxws:endpoint element in a spring container 
> cxf-beans.xml, like
> > below:
> >
> > <snip>
> >         <jaxws:endpoint id="myEndpoint" 
> implementor="#genericProvider"
> >                 address="/myLocation/" serviceName="msp:MyService"
> >                 wsdlLocation="classpath:wsdl/MyWSDL.wsdl"
> >                 xmlns:msp="http://my.service">
> >         </jaxws:endpoint>
> > <snip>
> >
> > But this throws an NPE when I load the cxf-beans.xml using 
> Tomcat. The
> > relevant log4j logs are attached.
> >
> > Any ideas what's causing this?
> >
> > Thanks,
> > Dhiraj.
> >
> >
> 
> 
> -- 
> Dan Diephouse
> Envoi Solutions
> http://envoisolutions.com | http://netzooid.com/blog
> 

----------------------------
IONA Technologies PLC (registered in Ireland)
Registered Number: 171387
Registered Address: The IONA Building, Shelbourne Road, Dublin 4, Ireland

Re: Generic Provider server and WSDL metadata

Posted by Dan Diephouse <da...@envoisolutions.com>.
Hmmm I have no idea how that's occurring... Any chance your wsdl has zero
operations in it?

- Dan

On 8/17/07, Bokde, Dhiraj <DB...@iona.com> wrote:
>
> Hi,
>
> I am trying to build a generic server using Provider<DOMSource>. But I
> want to make the WSDL metadata, wsdlLocation, serviceName, portName,
> etc. to be user configurable, without having to re-compile the Provider
> with new WebServiceProvider annotations for every new WSDL.
>
> I thought I'd be able to do this with an empty WebServiceProvider
> annotation for my Provider like below:
>
> <snip>
> @WebServiceProvider()
> @ServiceMode(value = Service.Mode.MESSAGE)
> public final class GenericMessageProvider implements Provider<DOMSource>
> {
> <snip>
>
> And the jaxws:endpoint element in a spring container cxf-beans.xml, like
> below:
>
> <snip>
>         <jaxws:endpoint id="myEndpoint" implementor="#genericProvider"
>                 address="/myLocation/" serviceName="msp:MyService"
>                 wsdlLocation="classpath:wsdl/MyWSDL.wsdl"
>                 xmlns:msp="http://my.service">
>         </jaxws:endpoint>
> <snip>
>
> But this throws an NPE when I load the cxf-beans.xml using Tomcat. The
> relevant log4j logs are attached.
>
> Any ideas what's causing this?
>
> Thanks,
> Dhiraj.
>
>


-- 
Dan Diephouse
Envoi Solutions
http://envoisolutions.com | http://netzooid.com/blog