We have an application that should consume an external web service. To do this, we created a set of Java artifacts from WSDL via Maven, using the wsdl2java target provided by the cxf-codegen-plugin plugin.
In the application, we want to set the endpoint to use for calling the web service at runtime (to serve the URLs of the web service endpoints in test environments), and therefore we needed the following code:
private <T> T createServiceObject(final Class<T> p_seiClass) throws MalformedURLException { final Service serviceFactory = Service.create(new URL(wsdlLocation), new QName(targetNamespace, serviceName)); final T service = serviceFactory.getPort(p_seiClass); ((BindingProvider) service).getRequestContext().put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY, "endpoint"); return service; }
When the code starts with an error in the line serviceFactory.getPort with the following execution:
javax.xml.ws.WebServiceException: class ZZZ.YYYwebservice.v5.types.ProcessUIRequestResponse do not have a property of the name ProcessUIRequestResult at com.sun.xml.internal.ws.client.sei.ResponseBuilder$DocLit.<init>(ResponseBuilder.java:512) at com.sun.xml.internal.ws.client.sei.SEIMethodHandler.buildResponseBuilder(SEIMethodHandler.java:172) at com.sun.xml.internal.ws.client.sei.SyncMethodHandler.<init>(SyncMethodHandler.java:86) at com.sun.xml.internal.ws.client.sei.SEIStub.<init>(SEIStub.java:83) at com.sun.xml.internal.ws.client.WSServiceDelegate.createEndpointIFBaseProxy(WSServiceDelegate.java:641) at com.sun.xml.internal.ws.client.WSServiceDelegate.getPort(WSServiceDelegate.java:344) at com.sun.xml.internal.ws.client.WSServiceDelegate.getPort(WSServiceDelegate.java:326) at com.sun.xml.internal.ws.client.WSServiceDelegate.getPort(WSServiceDelegate.java:364) at com.sun.xml.internal.ws.client.WSServiceDelegate.getPort(WSServiceDelegate.java:368) at javax.xml.ws.Service.getPort(Service.java:172) at com.XXX.XXX.XXX.YYY.integration.facade.jaxws.ProcessUIRequestFacadeJaxws.createServiceObject(ProcessUIRequestFacadeJaxws.java:53) at com.XXX.XXX.XXX.YYY.integration.facade.jaxws.ProcessUIRequestFacadeJaxws.processUIRequest(ProcessUIRequestFacadeJaxws.java:39) at com.XXX.XXX.XXX.YYY.integration.facade.jaxws.ProcessUIRequestFacadeJaxwsTest.test(ProcessUIRequestFacadeJaxwsTest.java:49) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:60) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:37) at java.lang.reflect.Method.invoke(Method.java:611) at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:47) at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12) at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:44) at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17) at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:271) at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:70) at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50) at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238) at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63) at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236) at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53) at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229) at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26) at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:27) at org.junit.runners.ParentRunner.run(ParentRunner.java:309) at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50) at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197) Caused by: javax.xml.bind.JAXBException: ProcessUIRequestResult is not a valid property on class ZZZ.YYYwebservice.v5.types.ProcessUIRequestResponse at com.sun.xml.internal.bind.v2.runtime.JAXBContextImpl.getElementPropertyAccessor(JAXBContextImpl.java:954) at com.sun.xml.internal.ws.client.sei.ResponseBuilder$DocLit.<init>(ResponseBuilder.java:501) ... 37 more
Below I see javax.xml.bind.JAXBException: ProcessUIRequestResult is not a valid property in the ZZZ.YYYwebservice.v5.types.ProcessUIRequestResponse class , which assumes something is wrong with the generated ProcessUIRequestResponse.java file.
I looked at this file and see nothing obvious (ProcessUIRequestResult is defined in the class and has getter and setter). Class below:
package YYY.ZZZwebservice.v5.types; import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.XmlElement; import javax.xml.bind.annotation.XmlRootElement; import javax.xml.bind.annotation.XmlType; import YYY.ZZZbase.BaseVO; @XmlAccessorType(XmlAccessType.FIELD) @XmlType(name = "", propOrder = { "processUIRequestResult" }) @XmlRootElement(name = "ProcessUIRequestResponse") public class ProcessUIRequestResponse { @XmlElement(name = "ProcessUIRequestResult") protected BaseVO processUIRequestResult; public BaseVO getProcessUIRequestResult() { return processUIRequestResult; } public void setProcessUIRequestResult(BaseVO value) { this.processUIRequestResult = value; } public ProcessUIRequestResponse withProcessUIRequestResult(BaseVO value) { setProcessUIRequestResult(value); return this; } }
Can anyone understand what the problem is? I can not notice anything obvious and could not find any information about what could be the problem.
Thanks for your help in advance.
EDIT - UPDATE FOR 20/09 BASED ON LORENZO ANSWER
Unfortunately, the web service is a third-party service, and I do not have access to change the XSD. I used the WSDL server URL when creating Java from it.
However, as a test, I changed the generated ProcessUIRequestResponse.java to change the property to start with an uppercase letter to match the WSDL, and the same error was thrown.
Does anyone have any ideas?
FURTHER CHANGE 26/09 TO ENSURE UPDATES **
I did more research on this and found that this is actually a problem with how the service endpoint interface is created. This is what is generated:
@WebService(targetNamespace = "http://zzz/yyywebservice/v5/types/", name = "Types") @XmlSeeAlso({ zzz.yyyentityview.ObjectFactory.class, zzz.yyyview.search.postcode.ObjectFactory.class, zzz.yyyentityview.validation.ObjectFactory.class, zzz.serializable_dictionary.ObjectFactory.class, zzz.yyyview.search.app.ObjectFactory.class, zzz.yyybase.ObjectFactory.class, zzz.yyybase.enums.ObjectFactory.class, zzz.yyyview.uw.ObjectFactory.class, zzz.yyyview.app.ObjectFactory.class, zzz.yyyview.search.bank.ObjectFactory.class, zzz.yyyview.search.list.ObjectFactory.class, zzz.yyyentityview.app.ObjectFactory.class, zzz.yyyentityview.client.ObjectFactory.class, ObjectFactory.class }) public interface Types { @WebResult(name = "ProcessUIRequestResult", targetNamespace = "") @ResponseWrapper(localName = "ProcessUIRequestResponse", targetNamespace = "http://zzz/yyywebservice/v5/types/", className = "zzz.yyywebservice.v5.types.ProcessUIRequestResponse") @RequestWrapper(localName = "ProcessUIRequest", targetNamespace = "http://zzz/yyywebservice/v5/types/", className = "zzz.yyywebservice.v5.types.ProcessUIRequest") @WebMethod(operationName = "ProcessUIRequest", action = "http://zzz/yyywebservice/v5/ProcessUIRequest") public zzz.yyybase.BaseVO processUIRequest( @WebParam(name = "ProcessUIRequest", targetNamespace = "http://zzz/yyywebservice/v5/types/") zzz.yyybase.BaseVO processUIRequest); @WebResult(name = "GetActivityStatusEntityResult", targetNamespace = "") @ResponseWrapper(localName = "GetActivityStatusEntityResponse", targetNamespace = "http://zzz/yyywebservice/v5/types/", className = "zzz.yyywebservice.v5.types.GetActivityStatusEntityResponse") @RequestWrapper(localName = "GetActivityStatusEntity", targetNamespace = "http://zzz/yyywebservice/v5/types/", className = "zzz.yyywebservice.v5.types.GetActivityStatusEntity") @WebMethod(operationName = "GetActivityStatusEntity", action = "http://zzz/yyywebservice/v5/GetActivityStatusEntity") public zzz.yyybase.ActivityStatusVOBase getActivityStatusEntity( @WebParam(name = "ProcessUIRequest", targetNamespace = "http://zzz/yyywebservice/v5/types/") zzz.yyybase.BaseVO processUIRequest); }
The problem is with the @WebResult annotation and the empty TargetNamespace field. When I manually edit the class and add what I would expect from targetNamespace (based on an XSD search), I can successfully call the web service.
I looked in the XSD for any missing namespace definitions or any other obvious errors, but I can't notice anything. Does anyone have any guidance as to where the targetNamespace or @WebResult is coming from?