title: Apache CXF wsdl download via SSL/TLS
body: <p>I have a cxf service running at </p>
  
  <pre><code>https://localhost:8443/services/MyService?wsdl
  </code></pre>
  
  <p>with client certificate required. The WSDL is not important here.</p>
  
  <p>I am able to invoke the service when I remove the client certificate or https requirement.</p>
  
  <p>The service and client classes were generated with cxf wsdl2java utility.
  </p>
  
  <p>Here is MyService.class:</p>
  
  <pre class="lang-java prettyprint-override"><code>package com.mycompany;
  
  import java.net.URL;
  import java.util.logging.Level;
  import java.util.logging.Logger;
  
  import javax.xml.namespace.QName;
  import javax.xml.ws.Service;
  import javax.xml.ws.WebEndpoint;
  import javax.xml.ws.WebServiceClient;
  import javax.xml.ws.WebServiceFeature;
  
  /**
   * This class was generated by Apache CXF 2.7.3 2013-03-29T13:59:37.423-03:00 Generated source version: 2.7.3
   */
  @WebServiceClient(name = "MyService", wsdlLocation = "myservice.wsdl", targetNamespace = "http://server/schemas/services")
  public class MyService extends Service {
  
      public final static URL WSDL_LOCATION;
  
      public final static QName SERVICE = new QName("http://server/schemas/services", "MyService");
      public final static QName MyServicePort = new QName("http://server/schemas/services", "MyServicePort");
      static {
          URL url = MyService.class.getResource("myservice.wsdl");
          if (url == null) {
              Logger.getLogger(MyService.class.getName()).log(Level.INFO, "Can not initialize the default wsdl from {0}", "myservice.wsdl");
          }
          WSDL_LOCATION = url;
      }
  
      public MyService(URL wsdlLocation) {
          super(wsdlLocation, SERVICE);
      }
  
      public MyService(URL wsdlLocation, QName serviceName) {
          super(wsdlLocation, serviceName);
      }
  
      public MyService() {
          super(WSDL_LOCATION, SERVICE);
      }
  
      /**
       * 
       * @return returns EncaminharMensagemPortType
       */
      @WebEndpoint(name = "MyServicePort")
      public MyServicePortType getMyServicePort() {
          return super.getPort(MyServicePort, MyServicePortType.class);
      }
  
      /**
       * 
       * @param features
       *            A list of {@link javax.xml.ws.WebServiceFeature} to configure on the proxy. Supported features not in the
       *            &lt;code&gt;features&lt;/code&gt; parameter will have their default values.
       * @return returns EncaminharMensagemPortType
       */
      @WebEndpoint(name = "MyServicePort")
      public MyServicePortType getMyServicePort(WebServiceFeature... features) {
          return super.getPort(MyServicePort, MyServicePortType.class, features);
      }
  
  }
  </code></pre>
  
  <p>Here is my client without client certificate requirement: (that work fine)</p>
  
  <pre class="lang-java prettyprint-override"><code>package com.mycompany;
  
  import java.net.URL;
  
  import javax.xml.namespace.QName;
  
  import com.mycompany.IdHolder;
  import com.mycompany.MyDataObject;
  
  public class CxfClientSslTest {
  
      public static void main(String[] args) {
          try {
  
              QName SERVICE_NAME = new QName("http://server/schemas/services", "MyService");
              URL wsdlURL = new URL("https://localhost:8443/services/MyService?wsdl");
              MyService ss = new MyService(wsdlURL, SERVICE_NAME);
              MyServicePortType port = ss.getMyServicePort();
  
              IdHolder mensagem = new IdHolder();
              mensagem.setId(1L);
              MyDataObject dataObject = port.getById(mensagem);
  
              System.out.println("Id: " + dataObject.getId());
          } catch (Exception e) {
              e.printStackTrace();
          }
      }
  }
  </code></pre>
  
  <p>And here is my client send his certificate:</p>
  
  <pre class="lang-java prettyprint-override"><code>package com.mycompany;
  
  import java.io.File;
  import java.io.FileInputStream;
  import java.io.IOException;
  import java.io.InputStream;
  import java.net.URL;
  import java.security.KeyStore;
  import java.security.KeyStoreException;
  import java.security.NoSuchAlgorithmException;
  import java.security.UnrecoverableKeyException;
  import java.security.cert.CertificateException;
  
  import javax.net.ssl.KeyManager;
  import javax.net.ssl.KeyManagerFactory;
  import javax.net.ssl.TrustManager;
  import javax.net.ssl.TrustManagerFactory;
  import javax.xml.namespace.QName;
  
  import org.apache.cxf.configuration.jsse.TLSClientParameters;
  import org.apache.cxf.endpoint.Client;
  import org.apache.cxf.frontend.ClientProxy;
  import org.apache.cxf.transport.http.HTTPConduit;
  
  public class CxfClientSslTest {
  
      public static void main(String[] args) {
          try {
  
              QName SERVICE_NAME = new QName("http://server/schemas/services", "MyService");
              URL wsdlURL = new URL("https://localhost:8443/services/MyService?wsdl");
              MyService ss = new MyService(wsdlURL, SERVICE_NAME);
              MyServicePortType port = ss.getMyServicePort();
  
              tslIt(port);
  
              IdHolder mensagem = new IdHolder();
              mensagem.setId(1L);
              MyDataObject dataObject = port.getById(mensagem);
  
              System.out.println("Id: " + dataObject.getId());
          } catch (Exception e) {
              e.printStackTrace();
          }
      }
  
      public static void tslIt(MyServicePortType port) throws KeyStoreException, NoSuchAlgorithmException, CertificateException, IOException,
              UnrecoverableKeyException {
          Client client = ClientProxy.getClient(port);
          HTTPConduit http = (HTTPConduit) client.getConduit();
  
          TLSClientParameters tlsClientParameters = http.getTlsClientParameters();
  
          KeyStore keyStore = getKeyStore();
          KeyStore trustStore = getTrustStore();
  
          KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
          TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
  
          keyManagerFactory.init(keyStore, "123456".toCharArray());
          KeyManager[] keyMgrs = keyManagerFactory.getKeyManagers();
          tlsClientParameters.setKeyManagers(keyMgrs);
  
          trustManagerFactory.init(trustStore);
          TrustManager[] trustManagers = trustManagerFactory.getTrustManagers();
          tlsClientParameters.setTrustManagers(trustManagers);
  
          tlsClientParameters.setDisableCNCheck(true);
      }
  
      public static KeyStore getKeyStore() throws KeyStoreException, NoSuchAlgorithmException, CertificateException, IOException {
          URL keyStoreUrl = CxfClientSslTest.class.getResource("/certs/client.jks");
          File keystoreFile = new File(keyStoreUrl.getPath());
          if (!keystoreFile.exists()) {
              throw new RuntimeException("keystore doesn't exists: " + keystoreFile.getAbsolutePath());
          }
  
          KeyStore keystore = KeyStore.getInstance(KeyStore.getDefaultType());
          InputStream keystoreInput = new FileInputStream(keystoreFile.getAbsolutePath());
          keystore.load(keystoreInput, "changeit".toCharArray());
          keystoreInput.close();
          return keystore;
      }
  
      public static KeyStore getTrustStore() throws KeyStoreException, NoSuchAlgorithmException, CertificateException, IOException {
          URL trustStoreUrl = CxfClientSslTest.class.getResource("/certs/client-trust.jks");
          File trustStoreFile = new File(trustStoreUrl.getPath());
          if (!trustStoreFile.exists()) {
              throw new RuntimeException("truststore doesn't exists: " + trustStoreFile.getAbsolutePath());
          }
  
          KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType());
          InputStream trustStoreInput = new FileInputStream(trustStoreFile.getAbsolutePath());
          trustStore.load(trustStoreInput, "changeit".toCharArray());
          trustStoreInput.close();
          return trustStore;
      }
  
  }
  </code></pre>
  
  <p>The TLS configuration both from client and server were checked and are ok. But when I run the program I get this:</p>
  
  <pre class="lang-java prettyprint-override"><code>Information: Can not initialize the default wsdl from myservice.wsdl
  javax.xml.ws.WebServiceException: org.apache.cxf.service.factory.ServiceConstructionException: Failed to create service.
      at org.apache.cxf.jaxws.ServiceImpl.&lt;init&gt;(ServiceImpl.java:149)
      at org.apache.cxf.jaxws.spi.ProviderImpl.createServiceDelegate(ProviderImpl.java:98)
      at javax.xml.ws.Service.&lt;init&gt;(Service.java:77)
      at com.mycompany.MyService.&lt;init&gt;(MyService.java:36)
      at com.mycompany.CxfClientSslTest.main(CxfClientSslTest.java:32)
  Caused by: org.apache.cxf.service.factory.ServiceConstructionException: Failed to create service.
      at org.apache.cxf.wsdl11.WSDLServiceFactory.&lt;init&gt;(WSDLServiceFactory.java:100)
      at org.apache.cxf.jaxws.ServiceImpl.initializePorts(ServiceImpl.java:199)
      at org.apache.cxf.jaxws.ServiceImpl.&lt;init&gt;(ServiceImpl.java:147)
      ... 4 more
  Caused by: javax.wsdl.WSDLException: WSDLException: faultCode=PARSER_ERROR: Problem parsing 'https://localhost:8443/services/MyService?wsdl'.: javax.net.ssl.SSLHandshakeException: java.security.cert.CertificateException: No name matching localhost found
      at com.ibm.wsdl.xml.WSDLReaderImpl.getDocument(Unknown Source)
      at com.ibm.wsdl.xml.WSDLReaderImpl.readWSDL(Unknown Source)
      at com.ibm.wsdl.xml.WSDLReaderImpl.readWSDL(Unknown Source)
      at org.apache.cxf.wsdl11.WSDLManagerImpl.loadDefinition(WSDLManagerImpl.java:262)
      at org.apache.cxf.wsdl11.WSDLManagerImpl.getDefinition(WSDLManagerImpl.java:205)
      at org.apache.cxf.wsdl11.WSDLServiceFactory.&lt;init&gt;(WSDLServiceFactory.java:98)
      ... 6 more
  Caused by: javax.net.ssl.SSLHandshakeException: java.security.cert.CertificateException: No name matching localhost found
      at sun.security.ssl.Alerts.getSSLException(Alerts.java:192)
      at sun.security.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1868)
      at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:276)
      at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:270)
      at sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1337)
      at sun.security.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:154)
      at sun.security.ssl.Handshaker.processLoop(Handshaker.java:868)
      at sun.security.ssl.Handshaker.process_record(Handshaker.java:804)
      at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:998)
      at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1294)
      at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1321)
      at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1305)
      at sun.net.www.protocol.https.HttpsClient.afterConnect(HttpsClient.java:523)
      at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(AbstractDelegateHttpsURLConnection.java:185)
      at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1296)
      at sun.net.www.protocol.https.HttpsURLConnectionImpl.getInputStream(HttpsURLConnectionImpl.java:254)
      at com.sun.org.apache.xerces.internal.impl.XMLEntityManager.setupCurrentEntity(XMLEntityManager.java:653)
      at com.sun.org.apache.xerces.internal.impl.XMLVersionDetector.determineDocVersion(XMLVersionDetector.java:189)
      at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:799)
      at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:764)
      at com.sun.org.apache.xerces.internal.parsers.XMLParser.parse(XMLParser.java:123)
      at com.sun.org.apache.xerces.internal.parsers.DOMParser.parse(DOMParser.java:240)
      at com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderImpl.parse(DocumentBuilderImpl.java:300)
      ... 12 more
  Caused by: java.security.cert.CertificateException: No name matching localhost found
      at sun.security.util.HostnameChecker.matchDNS(HostnameChecker.java:208)
      at sun.security.util.HostnameChecker.match(HostnameChecker.java:93)
      at sun.security.ssl.X509TrustManagerImpl.checkIdentity(X509TrustManagerImpl.java:347)
      at sun.security.ssl.X509TrustManagerImpl.checkTrusted(X509TrustManagerImpl.java:203)
      at sun.security.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:126)
      at sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1319)
      ... 30 more
  </code></pre>
  
  <p>I can see that the problem is happening before my https configuration get done, when cxf tries to download the wsdl.</p>
  
  <p>I made a research on how to make cxf use that https configuration to download the wsdl. It take me a lot of time, but I can't find the answer out there.</p>
  
  <p>So my question is: how to make cxf use the https configuration to download the wsdl?</p>
  
  <p>Please, I have the answer already and I intend to put it here. So, if you don't have a good answer, or better the answer, please don't post one.</p>