Search code examples
javaweb-serviceswsdljax-ws

How to specify wsdlLocation for local file


I am new to the game of web-service clients, and have generated code using the wsdl2java maven dependency.

I am packaging this project as a .war file.

My issue is that I do not know how to make the autogenerated client reach an endpoint across domains, and I also do not know how to set the client's wsdlLocation properly.

Starting with the latter: Inside of the autogenerated service class, I found a static URL WSDL_LOCATION attribute, as well as 'parameters?' to a WebServiceClient annotation.

@WebServiceClient(name = "my_service", 
                  wsdlLocation = "file:/c:/tmp/my_service.wsdl",
                  targetNamespace = "someAutoGenTargetNS/wsdl") 
public class my_service_Service extends Service {

    public final static URL WSDL_LOCATION;

    public final static QName SERVICE = new QName("someAutoGenTargetNS/wsdl", "my_service");
    public final static QName my_service = new QName("http://someAtuoGenTargetNS/wsdl", "my_service");
    static {
        URL url = null;
        try {
            url = new URL("file:/c:/tmp/my_service.wsdl");
        } catch (MalformedURLException e) {
            java.util.logging.Logger.getLogger(my_service_Service.class.getName())
                .log(java.util.logging.Level.INFO, 
                     "Can not initialize the default wsdl from {0}", "file:/c:/tmp/my_service.wsdl");
        }
        WSDL_LOCATION = url;
    }

Currently, the WSDL_LOCATION url is always set to null, as it can not find the filepath specified (which is expected). I have the wsdl and xsd stored in the resources folder, but do not know how to specify the path to reach that. I have tried

new URL("file:/resources/my_service.wsdl")
new URL("file:/src/main/java/resources/my_service.wsdl")
new URL("classpath:my_service.wsdl")

and quite a few others. What is the correct way to do this, and if it requires an xml-catalog, where can I find documentation about where to put the catalog.xml file.

And now the former: I believe my implementation to change the endpoint to the location I want is correct, and it is the wsdlLocation issue that is giving me a headache. Here is my implementation to change the endpoints. If this does not look right, simply point me in the direction of what to use, no need for a full implementation.

private static final QName SERVICE_NAME = new QName(""someAutoGenTargetNS/wsdl"", "my_service");
    private URL wsdlURL = my_service_Service.WSDL_LOCATION;
    my_service_Service ss;
    my_service port;
public my_service_client()
{
        //Redacted code for trusting all SSL Certs and hostnameVerifiers as it is not needed for the scope of this question
        this.ss = new my_service_Service(this.wsdlURL,SERVICE_NAME);
        this.port = ss.getMy_Service();
        BindingProvider bp = (BindingProvider) this.port;
        Map<String,Object> clientRequestContext = bp.getRequestContext();
        clientRequestContext.put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY, "https://New_Endpoint_IP");
//Basic auth header credentials
        clientRequestContext.put(BindingProvider.USERNAME_PROPERTY,"username");
        clientRequestContext.put(BindingProvider.PASSWORD_PROPERTY,"password");
}

Resources I attempted to understand prior to asking this question:

1 2 3 4 5 6 7+ 8

Conclusively, I am coming to the realization I would much rather work with HTTP than SOAP, but legacy systems require legacy interaction.

Error's received that lead me to believe this is a wsdlURL issue:

javax.xml.ws.soap.SOAPFaultException: Internal Error (from client)
org.apache.cxf.binding.soap.SoapFault: Internal Error (from client)

Solution

  • Figured out the issue (4 days of tracking the problem later, and i can solve it shortly after asking the question here...)

    This is indeed a valid way of setting the endpoint URL. That answers that question.

    I adopted the classLoader.getResource approach from this reference to set the wsdlLocation

    My new code became:

    @WebServiceClient(name = "my_service", 
                      wsdlLocation = "classpath:my_service.wsdl",
                      targetNamespace = "someAutoGenTargetNS/wsdl") 
    public class my_service_Service extends Service {
    
        public final static URL WSDL_LOCATION;
    
        public final static QName SERVICE = new QName("someAutoGenTargetNS/wsdl", "my_service");
        public final static QName my_service = new QName("http://someAtuoGenTargetNS/wsdl", "my_service");
        static {
            URL url = null;
                url = my_service.class.getClassLoader().getResource("my_service.wsdl");
            WSDL_LOCATION = url;
        }
    

    Lastly I realized that the most basic web-service call I was trying to utilize was incorrectly setting the request body. I had set the request_body to null, in stead of instantiation a new instance of the request class that was autogenerated. This is what was throwing these two errors, but I am sure fixing the above helped lead me to the solution by enforcing my understanding of how these pieces work together.