JIRA

  • Log In Access more options
    • Online Help
    • GreenHopper Help
    • Agile Answers
    • Use Agile By Default
    • Keyboard Shortcuts
    • About JIRA
    • JIRA Credits
    • What’s New
  • Dashboards Access more options (Alt+d)
  • Projects Access more options (Alt+p)
  • Issues Access more options (Alt+i)
  • Agile Access more options (Alt+g)
  • Create Issue
  • Mule
  • MULE-5227

Unable to set namespace, service and endpoint name because MuleServiceConfiguration has no effect

  • Agile Board
  • More Actions
  • Views
    • XML
    • Word
    • Printable

Details

  • Type: Bug Bug
  • Status: Open Open
  • Priority: Major Major
  • Resolution: Unresolved
  • Affects Version/s: 3.0.1
  • Fix Version/s: 3.1.x
  • Component/s: Modules: CXF
  • Labels:
    None
  • Environment:

    JDK 1.6, Mule Standalone 3.0.1 and deployed in JBoss 5.0.1 and 5.1.0 as EAR + JCA

  • User impact:
    High
  • Configuration:
    Hide

    <flow name="Flow">
    <inbound-endpoint address="${url}" />
    <cxf:jaxws-service
    service="MyService"
    port="MyPort"
    serviceClass="CustomProvider"
    namespace="Namespace"
    wsdlLocation="myService.wsdl">
    </cxf:jaxws-service>
    <component>
    <singleton-object class="CustomProvider"/>
    </component>
    </flow>

    @WebServiceProvider
    @ServiceMode(value = Service.Mode.MESSAGE)
    public class CustomProvider implements Provider<SOAPMessage>
    {

    @Resource
    protected WebServiceContext context;

    @Override
    public SOAPMessage invoke(SOAPMessage message) {...}
    }

    Show
    <flow name="Flow"> <inbound-endpoint address="${url}" /> <cxf:jaxws-service service="MyService" port="MyPort" serviceClass="CustomProvider" namespace="Namespace" wsdlLocation="myService.wsdl"> </cxf:jaxws-service> <component> <singleton-object class="CustomProvider"/> </component> </flow> @WebServiceProvider @ServiceMode(value = Service.Mode.MESSAGE) public class CustomProvider implements Provider<SOAPMessage> { @Resource protected WebServiceContext context; @Override public SOAPMessage invoke(SOAPMessage message) {...} }
  • Similar Issues:
    None

Description

AbstractInboundMessageProcessorBuilder in initServiceFactory(ReflectionServiceFactoryBean svcFac) attempts to set MuleServiceConfiguration in front of all other service configurations for ReflectionServiceFactoryBean. This does not work for JaxWsServiceFactoryBean because JaxWsServiceFactoryBean.setServiceClass() adds WebServiceProviderConfiguration in front of MuleServiceConfiguration. Order of service configurations matters because CXF ReflectionServiceFactoryBean determines endpoint/port name by checking if it is set on ReflectionServiceFactoryBean (not set in Mule) and if not by taking it from first service configuration.

FIRST WORKAROUND:
Set service class first and then add MuleServiceConfiguration in AbstractInboundMessageProcessorBuilder.initServiceFactory(). Order is reversed in current 3.x codebase.

svcFac.setServiceClass(getServiceClass());
svcFac.getServiceConfigurations().add(0, new MuleServiceConfiguration(this));

Resulting service configurations:
serviceConfigurations ArrayList<E> (id=151)
elementData Object[10] (id=153)
[0] MuleServiceConfiguration (id=179)
[1] WebServiceProviderConfiguration (id=167)
[2] DefaultServiceConfiguration (id=155)
[3] AbstractWSDLBasedEndpointFactory$SoapBindingServiceConfiguration (id=158)

Unfortunately, this is not enough because JaxWsServerFactoryBean.create() results in another call to JaxWsServiceFactoryBean.setService() and now WebServiceProviderConfiguration is in front of MuleServcieConfiguration again.

Resulting call stack and service configurations:
serviceConfigurations ArrayList<E> (id=151)
elementData Object[10] (id=153)
[0] WebServiceProviderConfiguration (id=243)
[1] MuleServiceConfiguration (id=179)
[2] WebServiceProviderConfiguration (id=167)
[3] DefaultServiceConfiguration (id=155)
[4] AbstractWSDLBasedEndpointFactory$SoapBindingServiceConfiguration (id=158)

Thread [main] (Suspended)
JaxWsServiceFactoryBean.initConfiguration(JaxWsImplementorInfo) line: 403
JaxWsServiceFactoryBean.setJaxWsImplementorInfo(JaxWsImplementorInfo) line: 398
JaxWsServiceFactoryBean.setServiceClass(Class<?>) line: 173
JaxWsServerFactoryBean(AbstractWSDLBasedEndpointFactory).initializeServiceFactory() line: 227
JaxWsServerFactoryBean(ServerFactoryBean).initializeServiceFactory() line: 157
JaxWsServerFactoryBean(AbstractWSDLBasedEndpointFactory).createEndpoint() line: 99
JaxWsServerFactoryBean(ServerFactoryBean).create() line: 117
JaxWsServerFactoryBean.create() line: 167

This seems like CXF 2.2.9 bug. More on this later.

Since WebServiceProviderConfiguration again is in front of MuleServiceConfiguration this results in default JAX-WS target namespace and service name, which is incorrect. MuleServiceConfiguration is never used because of the following in CXF ReflectionServiceFactoryBean:

protected String getServiceName() {
for (AbstractServiceConfiguration c : serviceConfigurations) {
String name = c.getServiceName();
if (name != null) { return name; }
}
throw new IllegalStateException("ServiceConfiguration must provide a value!");
}

protected String getServiceNamespace() {
if (serviceName != null) { return serviceName.getNamespaceURI(); }

for (AbstractServiceConfiguration c : serviceConfigurations) {
String name = c.getServiceNamespace();
if (name != null) { return name; } }
}
throw new IllegalStateException("ServiceConfiguration must provide a value!");
}

SECOND WORKAROUND:
Set serviceName explicitly on JaxWsServiceFactoryBean in AbstractInboundMessageProcessorBuilder.initServiceFactory(ReflectionServiceFactoryBean svcFac)
as it was done in Mule 2.x CxfMessageReceiver:

private void initServiceFactory(ReflectionServiceFactoryBean svcFac)
{
addIgnoredMethods(svcFac, Callable.class.getName());
addIgnoredMethods(svcFac, Initialisable.class.getName());
addIgnoredMethods(svcFac, Disposable.class.getName());
addIgnoredMethods(svcFac, ServiceAware.class.getName());

svcFac.setServiceClass(getServiceClass());
svcFac.getServiceConfigurations().add(0, new MuleServiceConfiguration(this));

//svcFac.setServiceClass(getServiceClass());
for (AbstractServiceConfiguration c : svcFac.getServiceConfigurations())

{ c.setServiceFactory(svcFac); }

String namespace = this.getNamespace();
String serviceName = this.getService();

if (serviceName != null && namespace == null)

{ namespace = svcFac.getServiceQName().getNamespaceURI(); }

else if (serviceName == null && namespace != null)

{ serviceName = svcFac.getServiceQName().getLocalPart(); }

if (serviceName != null)

{ svcFac.setServiceName(new QName(namespace, serviceName)); }

}

Later versions of CXF deal differently with building services so CXF upgrade may possibly resolve this problem. As it is, I'm not able to use web service provider below that worked in Mule 2.2.1

Regards,
Andre Piwoni

Activity

  • All
  • Comments
  • Work Log
  • History
  • Activity
  • Transitions
  • Commits
  • Source
  • Builds

CE Bamboo View RSS feed

People

  • Assignee:
    Unassigned
    Reporter:
    Andre Piwoni
Vote (0)
Watch (0)

Dates

  • Created:
    30/Nov/10 07:38 PM
    Updated:
    12/Jan/11 11:29 AM

Agile

  • View on Board
  • Atlassian JIRA (v5.0.7#734-sha1:8ad78a6)
  • Report a problem
  • Powered by a free Atlassian JIRA open source license for MuleForge. Try JIRA - bug tracking software for your team.