Running MPR project on WebSphere Liberty fails with SunCertPathBuilderExcep

Running a MPR project in WebSphere Liberty 20.0.0.9 (in this case I’m trying to run this thing https://gitlab.com/mvysny/vaadin14-mpr-gradle-demo via Intellij) fails with:

[ERROR   ]
 CWPKI0823E: SSL HANDSHAKE FAILURE:  A signer with SubjectDN [CN=*.vaadin.com, O=Vaadin Ltd, L=Turku, C=FI]
 was sent from the host [tools.vaadin.com:443]
.  The signer might need to be added to local trust store 
[/home/mavi/local/websphere-liberty-web/usr/servers/defaultServer/resources/security/key.p12], located in SSL configuration alias [defaultSSLConfig]
.  The extended error message from the SSL handshake exception is: [PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target]
.
[ERROR   ]
 SRVE0271E: Uncaught init() exception created by servlet [com.vaadin.mpr.MprServlet]
 in application [Gradle___vaadin14_mpr_gradle_demo_war]
: java.lang.RuntimeException: Unable to validate subscription. Please go to https://vaadin.com/pro/validate-license to check that your subscription is active. You can also find instructions for installing the license on a build server at https://vaadin.com/pro/validate-license
	at com.vaadin.pro.licensechecker.ProKeyValidator.validate(ProKeyValidator.java:58)
	at com.vaadin.pro.licensechecker.LicenseChecker.checkLicense(LicenseChecker.java:62)
	at com.vaadin.pro.licensechecker.LicenseChecker.checkLicense(LicenseChecker.java:36)
	at com.vaadin.mpr.core.MprServletService.verifyLicense(MprServletService.java:75)
	at com.vaadin.mpr.core.MprServletService.<init>(MprServletService.java:64)
	at com.vaadin.mpr.core.AbstractMprServlet.createServletService(AbstractMprServlet.java:183)
	at com.vaadin.server.VaadinServlet.createServletService(VaadinServlet.java:380)
	at com.vaadin.server.VaadinServlet.init(VaadinServlet.java:210)
	at com.ibm.ws.webcontainer.servlet.ServletWrapper.init(ServletWrapper.java:291)
	at [internal classes]

Caused by: javax.net.ssl.SSLHandshakeException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
	at java.base/sun.security.ssl.Alert.createSSLException(Alert.java:131)
	at java.base/sun.security.ssl.TransportContext.fatal(TransportContext.java:326)
	at java.base/sun.security.ssl.TransportContext.fatal(TransportContext.java:269)
	at java.base/sun.security.ssl.TransportContext.fatal(TransportContext.java:264)
	at java.base/sun.security.ssl.CertificateMessage$T12CertificateConsumer.checkServerCerts(CertificateMessage.java:645)
	at java.base/sun.security.ssl.CertificateMessage$T12CertificateConsumer.onCertificate(CertificateMessage.java:464)
	at java.base/sun.security.ssl.CertificateMessage$T12CertificateConsumer.consume(CertificateMessage.java:360)
	at java.base/sun.security.ssl.SSLHandshake.consume(SSLHandshake.java:392)
	at java.base/sun.security.ssl.HandshakeContext.dispatch(HandshakeContext.java:444)
	at java.base/sun.security.ssl.HandshakeContext.dispatch(HandshakeContext.java:422)
	at java.base/sun.security.ssl.TransportContext.dispatch(TransportContext.java:183)
	at java.base/sun.security.ssl.SSLTransport.decode(SSLTransport.java:171)
	at java.base/sun.security.ssl.SSLSocketImpl.decode(SSLSocketImpl.java:1403)
	at java.base/sun.security.ssl.SSLSocketImpl.readHandshakeRecord(SSLSocketImpl.java:1309)
	at java.base/sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:440)
	at java.base/sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:411)
	at java.base/sun.net.www.protocol.https.HttpsClient.afterConnect(HttpsClient.java:567)
	at java.base/sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(AbstractDelegateHttpsURLConnection.java:185)
	at java.base/sun.net.www.protocol.https.HttpsURLConnectionImpl.connect(HttpsURLConnectionImpl.java:168)
	at com.vaadin.pro.licensechecker.ProKeyValidator.queryServer(ProKeyValidator.java:107)
	at com.vaadin.pro.licensechecker.ProKeyValidator.validate(ProKeyValidator.java:42)
	... 9 more
Caused by: java.security.cert.CertificateException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
	at com.ibm.ws.ssl.core.WSX509TrustManager.processServerTrustError(WSX509TrustManager.java:938)
	at [internal classes]

	at java.base/sun.security.ssl.CertificateMessage$T12CertificateConsumer.checkServerCerts(CertificateMessage.java:629)
	... 25 more

[ERROR   ]
 SRVE0276E: Error while initializing Servlet [com.vaadin.mpr.MprServlet]
: javax.servlet.ServletException: SRVE0207E: Uncaught initialization exception created by servlet
	at com.ibm.ws.webcontainer.servlet.ServletWrapper.init(ServletWrapper.java:360)
	at [internal classes]

Caused by: java.lang.RuntimeException: Unable to validate subscription. Please go to https://vaadin.com/pro/validate-license to check that your subscription is active. You can also find instructions for installing the license on a build server at https://vaadin.com/pro/validate-license
	at com.vaadin.pro.licensechecker.ProKeyValidator.validate(ProKeyValidator.java:58)
	at com.vaadin.pro.licensechecker.LicenseChecker.checkLicense(LicenseChecker.java:62)
	at com.vaadin.pro.licensechecker.LicenseChecker.checkLicense(LicenseChecker.java:36)
	at com.vaadin.mpr.core.MprServletService.verifyLicense(MprServletService.java:75)
	at com.vaadin.mpr.core.MprServletService.<init>(MprServletService.java:64)
	at com.vaadin.mpr.core.AbstractMprServlet.createServletService(AbstractMprServlet.java:183)
	at com.vaadin.server.VaadinServlet.createServletService(VaadinServlet.java:380)
	at com.vaadin.server.VaadinServlet.init(VaadinServlet.java:210)
	at com.ibm.ws.webcontainer.servlet.ServletWrapper.init(ServletWrapper.java:291)
	... 1 more
Caused by: javax.net.ssl.SSLHandshakeException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
	at java.base/sun.security.ssl.Alert.createSSLException(Alert.java:131)
	at java.base/sun.security.ssl.TransportContext.fatal(TransportContext.java:326)
	at java.base/sun.security.ssl.TransportContext.fatal(TransportContext.java:269)
	at java.base/sun.security.ssl.TransportContext.fatal(TransportContext.java:264)
	at java.base/sun.security.ssl.CertificateMessage$T12CertificateConsumer.checkServerCerts(CertificateMessage.java:645)
	at java.base/sun.security.ssl.CertificateMessage$T12CertificateConsumer.onCertificate(CertificateMessage.java:464)
	at java.base/sun.security.ssl.CertificateMessage$T12CertificateConsumer.consume(CertificateMessage.java:360)
	at java.base/sun.security.ssl.SSLHandshake.consume(SSLHandshake.java:392)
	at java.base/sun.security.ssl.HandshakeContext.dispatch(HandshakeContext.java:444)
	at java.base/sun.security.ssl.HandshakeContext.dispatch(HandshakeContext.java:422)
	at java.base/sun.security.ssl.TransportContext.dispatch(TransportContext.java:183)
	at java.base/sun.security.ssl.SSLTransport.decode(SSLTransport.java:171)
	at java.base/sun.security.ssl.SSLSocketImpl.decode(SSLSocketImpl.java:1403)
	at java.base/sun.security.ssl.SSLSocketImpl.readHandshakeRecord(SSLSocketImpl.java:1309)
	at java.base/sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:440)
	at java.base/sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:411)
	at java.base/sun.net.www.protocol.https.HttpsClient.afterConnect(HttpsClient.java:567)
	at java.base/sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(AbstractDelegateHttpsURLConnection.java:185)
	at java.base/sun.net.www.protocol.https.HttpsURLConnectionImpl.connect(HttpsURLConnectionImpl.java:168)
	at com.vaadin.pro.licensechecker.ProKeyValidator.queryServer(ProKeyValidator.java:107)
	at com.vaadin.pro.licensechecker.ProKeyValidator.validate(ProKeyValidator.java:42)
	... 9 more
Caused by: java.security.cert.CertificateException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
	at com.ibm.ws.ssl.core.WSX509TrustManager.processServerTrustError(WSX509TrustManager.java:938)
	at [internal classes]

	at java.base/sun.security.ssl.CertificateMessage$T12CertificateConsumer.checkServerCerts(CertificateMessage.java:629)
	... 25 more

I have the ~/.vaadin/proKey file properly present in my home. Could it be that WebSphere’s built-in trust store doesn’t contain certificates for signing authority which vended the vaadin.com certificate?

It turns out that WebSphere doesn’t trust the vaadin.com certificate. To work around the issue, you need to download the certificate and then import it into the WebSphere’s keystore.

To download the certificate, go to https://vaadin.com with your browser. I’ll use Firefox. Then click the tiny lock icon to the left of the URL bar, then the right arrow next to “Connection secure”, then “More Information”, then “View Certificate”. In the *.vaadin.com tab, find “Download” and click “PEM (cert)” to download the vaadin-com.pem file.

In order to register the certificate into WebSphere Liberty, run this tiny command:

keytool -importcert -keystore /home/mavi/local/websphere-liberty-web/usr/servers/defaultServer/key.p12 -trustcacerts -alias vaadin -file /home/mavi/Downloads/vaadin-com.pem -storetype PKCS12 -storepass FSnDNKtIgCrkDxmdWsmfo6x

You will find the keystore password in the /home/mavi/local/websphere-liberty-web/usr/servers/defaultServer/server.env file.