JAXBException: not a valid property on class
Asked Answered
T

5

14

We have an application which needs to consume an external web service. To do this we have generated the set of Java artifacts from the WSDL via Maven using the wsdl2java goal provided by the cxf-codegen-plugin plugin.

In the application we want to set the endpoint to use for the web service call at runtime (to cater for different web service endpoint URLs in test environments) and so have written some code as follows to do this for us:

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 runs it fails on the serviceFactory.getPort line with the following execption:

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

At the bottom I can see javax.xml.bind.JAXBException: ProcessUIRequestResult is not a valid property on class ZZZ.YYYwebservice.v5.types.ProcessUIRequestResponse which suggests that something is wrong with the generated ProcessUIRequestResponse.java file.

I've looked at that file and can't see anything obvious (ProcessUIRequestResult is defined in the class and has a getter and setter). The class is 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;


/**
 * <p>Java class for anonymous complex type.
 * 
 * <p>The following schema fragment specifies the expected content contained within this class.
 * 
 * <pre>
 * &lt;complexType>
 *   &lt;complexContent>
 *     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
 *       &lt;sequence>
 *         &lt;element name="ProcessUIRequestResult" type="{http://YYY/ZZZbase/}BaseVO" minOccurs="0"/>
 *       &lt;/sequence>
 *     &lt;/restriction>
 *   &lt;/complexContent>
 * &lt;/complexType>
 * </pre>
 * 
 * 
 */
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "", propOrder = {
    "processUIRequestResult"
})
@XmlRootElement(name = "ProcessUIRequestResponse")
public class ProcessUIRequestResponse {

    @XmlElement(name = "ProcessUIRequestResult")
    protected BaseVO processUIRequestResult;

    /**
     * Gets the value of the processUIRequestResult property.
     * 
     * @return
     *     possible object is
     *     {@link BaseVO }
     *     
     */
    public BaseVO getProcessUIRequestResult() {
        return processUIRequestResult;
    }

    /**
     * Sets the value of the processUIRequestResult property.
     * 
     * @param value
     *     allowed object is
     *     {@link BaseVO }
     *     
     */
    public void setProcessUIRequestResult(BaseVO value) {
        this.processUIRequestResult = value;
    }

    public ProcessUIRequestResponse withProcessUIRequestResult(BaseVO value) {
        setProcessUIRequestResult(value);
        return this;
    }

}

Does anyone have any idea what the problem could be? I can't spot anything obvious and have not been able to find any information as to what the issue could be.

Thanks for your help in advance.

EDIT - UPDATE ON 20/09 BASED ON LORENZO'S ANSWER

Unfortunately the web service is a third party service and I don't have access to modify the XSDs. I used the server URL of the WSDL when generating the Java from it.

However, as a test I modified 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 EDIT on 26/09 TO PROVIDE UPDATES **

I've been doing more investigation into this and have found that it actually looks to be an issue with the way in which the service endpoint interface is generated. This is what is generated:

/**
 * This class was generated by Apache CXF 2.5.2 2013-09-26T13:05:17.389+01:00 Generated source version: 2.5.2
 * 
 */
@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 blank targetNamespace. When I manually edit the class and add what I would expect the targetNamespace to be (based on looking in the XSDs), I can sucessfully invoke the web service.

I've looked in the XSDs for any missing namespace definitions or any other obvious errors but I can't spot anything. Does anyone have any pointers as to where the targetNamespace or @WebResult is generated from?

Trinh answered 19/9, 2013 at 13:50 Comment(2)
How did you solve this?Pyoid
Your second update worked for me.Pastorale
M
4

Just add the package-info.java like this:

package-info.java :

@XmlSchema(
   namespace = "http://www.eijux.com/webservices/",
   elementFormDefault = XmlNsForm.QUALIFIED
)
package com.starlims.webservices;
Monetta answered 23/3, 2019 at 18:51 Comment(1)
It can be generated by tools (jdk/bin/wsimport.exe)Monetta
A
2

It can be a matter of how the wsdl2java is naming the package. If the targetNamespace (wsdl) is in camel case notation, your package needs to be camel case too. E.g.:

For targetNamespace="http://your.domain/WebAdminServices/WebSiteMgmt"

package domain.your.webAdminServices.webSiteMgmt; --> WORKS :)

package domain.your.webadminservices.websitemgmt; --> NOT WORKS :(

Hope it helps,

Luis

Alliber answered 7/11, 2013 at 15:4 Comment(1)
wouldn't it be domain.your.webAdminServices.whatever ?Odessa
F
1

I had similar problem and I found something on this link you should try the following:

  1. add the package-info.java buildpath
  2. compile and import the new package-info.java for your service and keep the different services in different services
  3. Download the new package-info.java file from wsdl
Fagen answered 23/12, 2015 at 14:37 Comment(0)
R
1

A workaround: use jaxws-maven-plugin instead. https://mvnrepository.com/artifact/org.codehaus.mojo/jaxws-maven-plugin

The same problem happened in my project. cxf can't generate targetNamespace but jaxws can given the same wsdl file.

Reflectance answered 9/8, 2018 at 9:25 Comment(0)
O
0

Javabean property names are traditionally lowercase. You have a capitalized tag name in your WSDL, i.e. ProcessUIRequestResult, but a lowercase property processUIRequestResult in your class, implied by method names setProcessUIRequestResult and getProcessUIRequestResult.

The WSDL to Java code generation appears correct, but it doesn't imply that other library code respects the WSDL and/or the Java annotation.

Can you make it work with lowercase element names?

Osmic answered 19/9, 2013 at 15:46 Comment(2)
Thanks - please see the update to the question for my findings on this.Trinh
I asked you to try lowercase element names in the WSDL and actual documents, to appease the (presumably buggy) XML processing part of the libraries, not uppercase property names in the code generation part of the libraries. You can set up a test with your own WSDL and documents, setting aside the actual webservice you need to consume; you'll probably end up selecting another library anyway.Osmic

© 2022 - 2024 — McMap. All rights reserved.