18

I have a web service that I have JAX-WS generated client bindings as below:

// web service client generated by JAX-WS
@WebServiceClient( ... )
public class WebService_Service extends Service {

    public WebService_Service(URL wsdlLocation, QName serviceName) {
        super(wsdlLocation, serviceName);
    }

    WebService getWebServiceSOAP() {
        // ...
    }
}

I want to be able to create an instance of this that points to a remote service like:

WebService_Service svc = new WebService_Service(
    new URL("http://www.example.com/ws?wsdl"),
    new QName("http://www.example.com/ws", "WebService"));

But that downloads the WSDL from http://www.example.com/ws?wsdl which I don't want to do.

Is there a way to stop the downloading of that WSDL, but still point to that same endpoint?

oconnor0
  • 3,154
  • 6
  • 34
  • 52

3 Answers3

21

I resolved this by specifying null for the WSDL URL in the client, as well as specifying the endpoint address explicitly:

WebService_Service svc = new WebService_Service(
  null,
  new QName("http://www.example.com/ws", "WebService"));
WebService port = svc.getPort(WebService.class);
BindingProvider bindingProvider = (BindingProvider) port;
bindingProvider.getRequestContext()
  .put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY,
    "http://www.example.com/real_endpoint_url_goes_here");

See: http://shrubbery.homeip.net/c/display/W/Consuming+a+Web+Service+with+Java+6+and+JAX-WS#ConsumingaWebServicewithJava6andJAX-WS-IgnoringtheWSDLCompletely

Joshua Davis
  • 3,499
  • 1
  • 26
  • 29
  • 1
    I've seen this also working with the no-args constructor of a service - in your case WebService_Service(). I don't know what is a better practice, to use the no-args constructor or the (null,QName) one as you do. – Marcus Junius Brutus Sep 26 '13 at 19:58
  • 2
    For me this wasn't as simple. The `@WebServiceClient` annotation has a `wsdlLocation` attribute that contains an absolute path to the WSDL. When removing this manually (which you really don't want to do), I got the following Exception: `com.sun.xml.ws.streaming.XMLStreamReaderException: XML reader error: com.ctc.wstx.exc.WstxUnexpectedCharException: Unexpected character 'a' (code 97) in prolog; expected '<'`. Seems it really does expect a WSDL file. – Dormouse Mar 07 '14 at 15:04
  • 1
    My platform is WebLogic 12c by the way. Also, the link in your answer is dead. – Dormouse Mar 07 '14 at 15:13
  • Thanks @Dormouse ... I'll update the link. My domain name had to change. :( – Joshua Davis Mar 12 '14 at 19:31
  • @MarcusJuniusBrutus That is a good question. If I find an answer, I'll try to post it here. :) – Joshua Davis Mar 12 '14 at 19:33
  • 1
    My solution is similar, using a dummy wsdl without address and setting a valid address at runtime: http://stackoverflow.com/a/25855467/2025769 – Jackson Cassimiro Sep 15 '14 at 19:28
  • @Dormouse I have the same problem, finnally you find a solution? com.sun.xml.ws.streaming.XMLStreamReaderException: XML reader error: com.ctc.wstx.exc.WstxUnexpectedCharException: Unexpected character 'a' (code 97) in prolog; expected '<' – mls_dev Aug 13 '15 at 13:07
2

The WSDL files might contain configuration options that the generated stubs don't contain, so they are needed at runtime. You can provide them locally in your class path.

The following maven pom.xml worked for me after placing the WSDL files of the service I'm using into my ${basedir}\src\main\resources\META-INF\wsdl folder:

<plugin>
  <groupId>org.jvnet.jax-ws-commons</groupId>
  <artifactId>jaxws-maven-plugin</artifactId>
  <version>2.3</version>
  <executions>
    <execution>
      <id>MyService</id>
      <goals>
        <goal>wsimport</goal>
      </goals>
      <configuration>
        <!-- this resolves naming conflicts within the wsdl - there are several copies of fault report objects which clash otherwise. -->
        <args>
          <arg>-B-XautoNameResolution</arg>
        </args>

        <packageName>de.xyz</packageName>
        <wsdlDirectory>${basedir}\src\main\resources\META-INF\wsdl</wsdlDirectory>
        <wsdlFiles>
          <wsdlFile>MyService.wsdl</wsdlFile>
        </wsdlFiles>
        <wsdlLocation>META-INF/wsdl/MyService.wsdl</wsdlLocation>                           
      </configuration>
    </execution>
  [...]

At runtime, the wsdl files will be loaded from the class path.

Twilite
  • 873
  • 9
  • 22
1

I had the same problem and I solved this, but I can't reveal it with your sample, because it depends on the wsdl.

Here is my code, track the solution:

    //This is the input object for the webservice
    GetDocumentInfoInput input = new GetDocumentInfoInput();
    input.setBarcode(barcode);
    //I instantiate the WS
    MAKSpcIntSpcWFSpcScannerInfo_Service service  = new MAKSpcIntSpcWFSpcScannerInfo_Service();
    //I get the WS port
    MAKSpcIntSpcWFSpcScannerInfo         port     = service.getMAKSpcIntSpcWFSpcScannerInfo();
    WSBindingProvider                    provider = (WSBindingProvider)port;
    //This is the row what set the URL for the WS
    provider.getRequestContext().put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY, url);
    //This is the WS calling
    GetDocumentInfoOutput                output   = port.getDocumentInfo(input);
Csujo
  • 507
  • 2
  • 6