I need to consume a web service which was built under Https in java. The Web Service Client was generated using Eclipse and to call it I use the following code:
ServicioTimbradoPruebasLocator ServicioTimbradoLocator = new ServicioTimbradoPruebasLocator();
ServicioTimbradoPruebasSoap ServicioTimbrado = ServicioTimbradoLocator.getServicioTimbradoPruebasSoap();
javax.xml.rpc.Stub s =((javax.xml.rpc.Stub)ServicioTimbrado);
s._setProperty(javax.xml.rpc.Stub.USERNAME_PROPERTY, "XXXXXXXX");
s._setProperty(javax.xml.rpc.Stub.PASSWORD_PROPERTY, "psswd");
String resultado = ServicioTimbrado.generaTimbre(xml.getBytes());
System.out.println("resultado: " +resultado);
On this line String resultado = ServicioTimbrado.generaTimbre(xml.getBytes()); I get the following error:
AxisFault
[java] faultCode: {http://schemas.xmlsoap.org/soap/envelope/}Server.userException
[java] faultSubcode:
[java] faultString: javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
[java] faultActor:
[java] faultNode:
[java] faultDetail:
[java] {http://xml.apache.org/axis/}stackTrace:javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
[java] at sun.security.ssl.Alerts.getSSLException(Unknown Source)
[java] at sun.security.ssl.SSLSocketImpl.fatal(Unknown Source)
[java] at sun.security.ssl.Handshaker.fatalSE(Unknown Source)
[java] at sun.security.ssl.Handshaker.fatalSE(Unknown Source)
[java] at sun.security.ssl.ClientHandshaker.serverCertificate(Unknown Source)
[java] at sun.security.ssl.ClientHandshaker.processMessage(Unknown Source)
[java] at sun.security.ssl.Handshaker.processLoop(Unknown Source)
[java] at sun.security.ssl.Handshaker.process_record(Unknown Source)
[java] at sun.security.ssl.SSLSocketImpl.readRecord(Unknown Source)
[java] at sun.security.ssl.SSLSocketImpl.performInitialHandshake(Unknown Source)
[java] at sun.security.ssl.SSLSocketImpl.startHandshake(Unknown Source)
[java] at sun.security.ssl.SSLSocketImpl.startHandshake(Unknown Source)
[java] at org.apache.axis.components.net.JSSESocketFactory.create(JSSESocketFactory.java:186)
[java] at org.apache.axis.transport.http.HTTPSender.getSocket(HTTPSender.java:191)
[java] at org.apache.axis.transport.http.HTTPSender.writeToSocket(HTTPSender.java:404)
[java] at org.apache.axis.transport.http.HTTPSender.invoke(HTTPSender.java:138)
[java] at org.apache.axis.strategies.InvocationStrategy.visit(InvocationStrategy.java:32)
[java] at org.apache.axis.SimpleChain.doVisiting(SimpleChain.java:118)
[java] at org.apache.axis.SimpleChain.invoke(SimpleChain.java:83)
[java] at org.apache.axis.client.AxisClient.invoke(AxisClient.java:165)
[java] at org.apache.axis.client.Call.invokeEngine(Call.java:2784)
[java] at org.apache.axis.client.Call.invoke(Call.java:2767)
[java] at org.apache.axis.client.Call.invoke(Call.java:2443)
[java] at org.apache.axis.client.Call.invoke(Call.java:2366)
[java] at org.apache.axis.client.Call.invoke(Call.java:1812)
[java] at mx.com.timbrado.test.cfdi.ServicioTimbradoPruebasSoapStub.generaTimbre(ServicioTimbradoPruebasSoapStub.java:107)
[java] at natura.facturacion.general.GuardarFacturaElectronicav2.doPost(GuardarFacturaElectronicav2.java:136) ...
I want to know if there is a way to send the certificate among with the webservice call. More information about the wsdl contract and the java generated files could be found here
Depending on the version of Java you are using, one of the "recent" updates to the 1.6 JRE/JDK include a significant change in the global CACerts (the Trusted authority that signs SSL Certificats, for instance Verisign) to include some of the new certificate types that are around.
I recommend upgrading to the latest versions of Java to see if that works, if not, Option 2 is...
Using SSLPoke.java you can find out which certificates are missing, and the InstallCert.java to install them as follows;
If this still causes issues, can you include the output from sslpoke, example usage;
# java SSLPoke webserver.domain.com 443
Successfully connected
If ALL that doesnt work, and you can get the certificate file (crt) you can manually import the file using the keytool command (cacerts is a file that will be created in your local working directory; ensure you move it into the java security folder in your JRE/JDK);
keytool -import -trustcacerts -alias AddTrustExternalCARoot -file cetificate.crt -keystore cacerts