A la base, j'avais monté un appel WebService standard (il n'était pas sécurisé), lorsque du jour au lendemain, l'erreur suivante remonte :

Caused by: 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
	at com.sun.net.ssl.internal.ssl.Alerts.getSSLException(Alerts.java:174)
	at com.sun.net.ssl.internal.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1591)
	at com.sun.net.ssl.internal.ssl.Handshaker.fatalSE(Handshaker.java:187)
	at com.sun.net.ssl.internal.ssl.Handshaker.fatalSE(Handshaker.java:181)
	at com.sun.net.ssl.internal.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:975)
	at com.sun.net.ssl.internal.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:123)
	at com.sun.net.ssl.internal.ssl.Handshaker.processLoop(Handshaker.java:516)
	at com.sun.net.ssl.internal.ssl.Handshaker.process_record(Handshaker.java:454)
	at com.sun.net.ssl.internal.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:884)
	at com.sun.net.ssl.internal.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1096)
	at com.sun.net.ssl.internal.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1123)
	at com.sun.net.ssl.internal.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1107)
	at sun.net.www.protocol.https.HttpsClient.afterConnect(HttpsClient.java:405)
	at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(AbstractDelegateHttpsURLConnection.java:166)
	at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:977)
	at sun.net.www.protocol.https.HttpsURLConnectionImpl.getInputStream(HttpsURLConnectionImpl.java:234)
	at java.net.URL.openStream(URL.java:1009)
	at com.sun.xml.internal.ws.wsdl.parser.RuntimeWSDLParser.createReader(RuntimeWSDLParser.java:785)
	at com.sun.xml.internal.ws.wsdl.parser.RuntimeWSDLParser.resolveWSDL(RuntimeWSDLParser.java:236)
	at com.sun.xml.internal.ws.wsdl.parser.RuntimeWSDLParser.parse(RuntimeWSDLParser.java:107)
	... 11 more

Il se trouve que désormais, la communication doit être sécurisée (cryptée grâce à un certificat) et que l'utilisateur doit être authentifié.

Ma situation est telle que je n'ai pas d'accès direct au certificat du serveur. Je dois donc le récupérer dynamiquement. Pour ce faire, j'ai trouvé une petite classe java (en annexe) très pratique qui fonctionne à merveille ! Elle s'utilise comme ceci (dans un terminal) :

java InstallCert localhost:8181 monMotDePasse

Cela va automatiquement récupérer le certificat envoyé par le serveur (ici localhost sur le port 8181) et créer un keystore (jssecacerts) pour java avec le mot de passe 'monMotDePasse'.

Il suffit ensuite de copier ce fichier dans le projet (ou de mettre le dossier dans le classpath) et d'ajouter les lignes de code suivantes pour que Java puisse utiliser le certificat ainsi créé :

System.setProperty("javax.net.ssl.trustStore", "jssecacerts");
System.setProperty("javax.net.ssl.trustStorePassword", "monMotDePasse");

La mise en place de ce code permet de pouvoir communiquer avec le serveur de manière sécurisée.

Après réexecution, le serveur me lance encore l'erreur suivante (le client n'est pas authentifié) :

Caused by: java.io.IOException: Server returned HTTP response code: 401 for URL: https://localhost:8181/SNV3SRV-ws-war/WSEntryPointService?wsdl
	at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1241)
	at sun.net.www.protocol.https.HttpsURLConnectionImpl.getInputStream(HttpsURLConnectionImpl.java:234)
	at java.net.URL.openStream(URL.java:1009)
	at com.sun.xml.internal.ws.wsdl.parser.RuntimeWSDLParser.createReader(RuntimeWSDLParser.java:785)
	at com.sun.xml.internal.ws.wsdl.parser.RuntimeWSDLParser.resolveWSDL(RuntimeWSDLParser.java:236)
	at com.sun.xml.internal.ws.wsdl.parser.RuntimeWSDLParser.parse(RuntimeWSDLParser.java:107)
	... 11 more

Pour résoudre cela, je suis tombé sur ce post qui explique simplement qu'il faut créer une classe personnalisée pour l'authentification :

public class BasicHTTPAuthenticator extends Authenticator
{
    private String _userName;
    private String _password;
 
    public BasicHTTPAuthenticator(String userName, String password)
    {
        _userName = userName;
        _password = password;
    }
 
    @Override
    protected PasswordAuthentication getPasswordAuthentication()
    {
        if (this.getRequestingProtocol().equalsIgnoreCase("https")) return new PasswordAuthentication(_userName, _password.toCharArray());
        else return null;
    }
 
    public String getUserName() { return _userName; }
    public void setUserName(String userName) { _userName = userName; }
    public String getPassword() { return _password; }
    public void setPassword(String password) {  _password = password; }
}

Et il ne reste plus qu'à la mettre par défaut pour que Java s'occupe du reste :

Authenticator.setDefault(new BasicHTTPAuthenticator("username", "password"));

Pour le fun, une dernière erreur :

Caused by: java.security.cert.CertificateException: No name matching localhost found
	at sun.security.util.HostnameChecker.matchDNS(HostnameChecker.java:210)
	at sun.security.util.HostnameChecker.match(HostnameChecker.java:77)
	at com.sun.net.ssl.internal.ssl.X509TrustManagerImpl.checkIdentity(X509TrustManagerImpl.java:264)
	at com.sun.net.ssl.internal.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:250)
	at com.sun.net.ssl.internal.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:954)
	... 26 more

C'est simplement qu'aucun certificat ne correspond à l'url du serveur (localhost ici). Dans ce cas, il suffit de remplacer 'localhost' avec le nom de la machine (ou du serveur). Il est possible de le faire dynamiquement grâce au code suivant :

//try/catch...
String hostName = InetAddress.getLocalHost().getHostName();
urlWebService = urlWebService.replace("localhost", hostName);

Et désormais tout (re)fonctionne ! Au final, pas grand-chose à ajouter, mais c'est assez compliqué à trouver si on part de zéro et que l'on ne sait pas trop où chercher.